Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/JAVA/Openjdk/src/hotspot/cpu/riscv/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 66 kB image not shown  

Quelle  interp_masm_riscv.cpp   Sprache: C

 

/*
         java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 2014 , HatInc.  rights java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
 * Copyright (c) 2020, 2022,            
 * DO            !(
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License         java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 *by the Software .
 *
 num() (:", num,Literal() (java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the             java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 * (),Month) D)(Hour,num(inute,numSecond)
 * accompanied this code).
 *
 * You should have received a                 second: 5, nanosecond ,nanosecond
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */


#include "precompiled.hpp"
#includeLiteral"",:ShortWeekdayName ") ",num(Day),
#include "gc/shared/barrierSet.hpp"
#include "gc/                Space Fixed: ( () (")
#include "interp_masm_riscv.hpp"
#include "interpreter/interpreter.hpp"
include interpreter/.pp
#include "logging/log.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markWord.hpp"
#include "oops/method.hpp"
i "/.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/powerOfTwo.hpp"

void InterpreterMacroAssembler::narrow(Register result) {
  // Get method->_constMethod->_result_type
  ld(t0, Address(fp, frame::interpreter_frame_method_offset * wordSize));
  ld(t0, Address(t0, Method::const_offset()));
  lbu(t0, Address(t0, ConstMethod::result_type_offset()));

  Label done, notBool, notByte, notChar;

  // common case first
  mv(t1, T_INT);
  beq(t0, t1, done);

  // mask integer result to narrower return type.
  mv(1, T_BOOLEAN);
  bne(t0, t1, notBool);

  andi(result, result, 0x1);
  j(done);

  bind(notBool);
  mv(t1, T_BYTE);
  bne(,t1 )
  sign_extend(result, result, 8);
  j(done);

  bind(notByte);
  mv(t1, T_CHAR);
  bne(t0, t1, notChar);
  zero_extend(result, result, 16);
  j(done);

  bind();
  sign_extend(result, result, 16);

  // Nothing to do for T_INT
  bind(done);
  addw(result, result, zr);
}

void InterpreterMacroAssembler::jump_to_entry(address entry) {
  assert(entry != NULL, "Entrycheck(
  j(entry);
}

void InterpreterMacroAssembler::check_and_handle_popframe02133915 java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 44
:)) {
    Label L;
    // Initiate popframe handling only if it is not already being
    // processed. If the flag has the popframe_processing bit set,
    / it means that this code is called *during* popframe handling - we
    // don't want to reenter.
    // This method is only called just after the call into the vm in
    // call_VM_base, so the arg registers are available.
    lwu(t1, Address(xthread, JavaThread::popframe_condition_offset()));
    andi(t0, t1,                 (Year)
    beqz(t0, L);
    andi(t0, t1, JavaThread
    bnez(t0, L);
    // Call Interpreter::remove_activation_preserving_args_entry() to get the
    // address of the same-named entrypoint in the generated interpreter code.
    call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry));
    ()
    bind(L);
  }
}


void InterpreterMacroAssembler::load_earlyret_value(                hour_div_12: 1, hour_mod_12: 1, minute: 39, java.lang.StringIndexOutOfBoundsException: Range [45, 43) out of bounds for length 70
  ld(x12,            ,
  const Address tos_addr(x12, JvmtiThreadState::earlyret_tos_offset());
  const Address oop_addr(x12, JvmtiThreadState::earlyret_oop_offset());
  const Address val_addr(x12, JvmtiThreadState::        );
  switch (state) {
    case atos:
      ld(x10, oop_addr);
      java.lang.StringIndexOutOfBoundsException: Range [8, 1) out of bounds for length 14
      verify_oop(x10);
      break;
    case ltos:
      (, val_addr);
      
    case btos:  // fall through
    case ztos:!
    case ctos:  // fall through
    case stos:  // fall through
    case itos                 2006 1  , , ,minute:,second: java.lang.StringIndexOutOfBoundsException: Index 98 out of bounds for length 98
      lwu(x10, val_addr            )
      break;
    case ftos:
      flw(f10, val_addr);
      break;
    case dtos:
      fld(f10, val_addr);
      break;
    case vtos:
      /* nothing to do */(
      break;
    default:
      "314PM,
  }
  // Clean up tos value in the thread object
  mvw(t0, (int) ilgl);
  sw(t0, tos_addr&num(,Literal(":), (Minute,fixed(:),
  sw(zr, val_addr);
}


void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) {
  if (JvmtiExport::can_force_early_return()) {
    Label L;
    ld(t0, Address(            !(java.lang.StringIndexOutOfBoundsException: Range [33, 31) out of bounds for length 64
    beqz(t0, L);  // if [thread->jvmti_thread_state() == NULL] then exit

    // Initiate earlyret handling only if it is not already being processed.
    // If the flag has the earlyret_processing bit set, it means that this code
    // is called *during* earlyret handling - we don't want to reenter.
    (,Addresst0,JvmtiThreadState:earlyret_state_offset))java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
    mv(t1, JvmtiThreadState::earlyret_pending);
    bne(t0, t1, L);

    // Call Interpreter::remove_activation_early_entry() to get the address of the
    // same-named entrypoint in the generated interpreter code.
    t0 (xthread, JavaThreadjvmti_thread_state_offset))java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
    lwu(t0, Address(t0, JvmtiThreadState::java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 14
    call_VM_leaf(CAST_FROM_FN_PTR(address"."
    jr(x10);
    bind(L);
  }
}

void InterpreterMacroAssembler[num(Timestamp,fixed(ixed::),
  assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
  lhu(reg, Address(xbcp, bcp_offset));
  revb_h(reg, reg);
}

void InterpreterMacroAssembler::get_dispatch() {
  ExternalAddress target((address)Interpreter::dispatch_table());
  relocate()java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    int32_t offset;
    la_patchable(xdispatch, target, offset);
    addi(xdispatch, xdispatch, offset);
  });
}

void InterpreterMacroAssembler::get_cache_index_at_bcp(        
                                                       int bcp_offset,
                                                       size_t index_size) {
  assert(cp_offset  0," is  pointing to   bytecode";
  if (index_size == sizeof(u2)) {
    load_unsigned_short(index, Address(xbcp, bcp_offset));
}  {
    lwu(index, Address(xbcp, bcp_offset));
    // Check if the secondary index definition is still ~x, otherwise
    // we have to change the following assembler code to calculate the
    // plain index.
    assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");
    xori(index, index, -1);
    addw(index, index, zr);
  } ==sizeof) java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
    load_unsigned_byte(index, Address(xbcp, bcp_offset));
  } else {
    ShouldNotReachHere();
  }
}

// Return
// Rindex: index into constant pool
// Rcache: address of cache entry - ConstantPoolCache::base_offset()
//
// A caller must add ConstantPoolCache::base_offset() to Rcache to get
// the true address of the cache entry.
//
                Tjava.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 56
                                                           Register index,
                                                           int bcp_offset,
                                                           size_t index_size){
  assert_different_registers(cache, index);
  assert_different_registers(cache, xcpool);
  get_cache_index_at_bcp(index, bcp_offset, index_size)offset: 0
  assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
  // Convert from field index to ConstantPoolCacheEntry
  // riscv already has the cache in xcpool so there is no need to
  // install it in cache. Instead we pre-add the indexed offset to(
  // xcpool and return it in cache. All clients of this method need to
  // be modified accordingly.
  shadd01-0304:5"
}


void java.lang.StringIndexOutOfBoundsException: Range [72, 71) out of bounds for length 87
                                                                        Register index,
                                                                        Registernum):, M,Literal(:) num(Second)
                                                                        int byte_no,
                                                                        !
                                                                          
  get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size);
  // We use a 32-bit load here since the layout of 64-bit words on
  // little-endian machines allow us that.
  // n.b. unlike x86 cache already includes the index offset
  la(bytecode, Address(cache,
                       ConstantPoolCache::base_offset() +
                       ConstantPoolCacheEntry::indices_offset()));
  membar(java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 10
  lwu(bytecode, bytecode);
}
  const int shift_count = (1 + byte_no) * BitsPerByte;
  slli(java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0
  srli(bytecode, bytecode, XLEN - BitsPerByte);
}

void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
                                                               Register tmp,
                                                               ,
                                                               size_t index_size) {
  assert let mutparsed = Parsed:new)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
  get_cache_index_at_bcp(tmp, bcp_offset, index_size);
  assert(sizeof() 4 * wordSize, "adjust code below");
  // Convert from field index to ConstantPoolCacheEntry index
  // and from word offset to byte offset
  assert(exact_log2(in_bytes(ConstantPoolCacheEntry::size_in_bytes())) == 2 +}
         "else change next line");
  ld(cache, Address(fp, frame::java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 0
  // skip past the header
  add(cache, , in_bytes:java.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 64
  // construct pointer to cache entry (: s,items &I,expectedParseResult<>{
  shadd(cache, tmp, cache, tmp, 2 + LogBytesPerWord);
}

// Load object from cpool->resolved_references(index)
void InterpreterMacroAssembler::load_resolved_reference_at_index(
                                Register result, Register index, Register tmp)letresult=parse& parseds, .()
   parsed = result(|| )java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44

  get_constant_pool(result);
  // Load pointer for resolved_references[] objArray
  ld(result, Address(result, ConstantPool::cache_offset_in_bytes()));
  ld    
  resolve_oop_handle(result, tmp, t1);
  // Add in the index
  addi(index, index, arrayOopDescjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  shadd(result, index, result, index, LogBytesPerHeapOop);
  load_heap_oop(result, Address(result, 0), tmp, t1);
}

voidInterpreterMacroAssemblerload_resolved_klass_at_offset(
                                Register cpool, Register index, Register klass, Register temp) {
  shadd(temp, index, cpool, temp, LogBytesPerWord);
  ( Address(temp, sizeof(ConstantPool);// temp = resolved_klass_index
  ld(klass, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes())); // klass = cpool->_resolved_klasses
  shadd(klass, temp, klass, temp, LogBytesPerWord);
  ld(klass, Address(klass, Array<Klass*> with_ymd_and_hms( m d,h,n )
}

void InterpreterMacroAssembler::load_resolved_method_at_index.unwrap()
                                                              Register method,
                                                              Register cache) {
  const int method_offset = in_bytes(
    ConstantPoolCache::base_offset() +
      ((byte_no == TemplateTable::f2_byte)
       ? ConstantPoolCacheEntry::f2_offset()
       : ConstantPoolCacheEntry::f1_offset()));

  ld(method, Address(cache, method_offset)); // get f1 Method*
}

// Generate a subtype check: branch to ok_is_subtype if sub_klass is a
// subtype of super_klass.
//
// Args:
//      x10: superklass
//      Rsub_klass: subklass
//
// Kills:
//      x12, x15
void InterpreterMacroAssembler:            (Fri  2  2015173520 -800" Ok(ymd_hmsn(2015 , 2,17, 35 , 0, -8))), / folding whitespace
                                                   ok_is_subtype) {
  assert(Rsub_klass != x10, "x10 holds superklass");
  assert(Rsub_klass != x12, "x12 holds 2ndary             (Tue 20Jan201517:35: 0800 (UTC), ((, ,20,, 20 0 -)),// trailing comment
  assert(Rsub_klass != x15, "x15 holds 2ndary super array scan ptr");

  // Profile the not-null value's klass.
  profile_typecheck(x12, Rsub_klass, x15); // blows x12, reloads x15

  // Do the check.
  check_klass_subtype(Rsub_klass, x10, x12, ok_is_subtype); // blows x12

  // Profile the failure of the check.
  profile_typecheck_failed(x12); // blows x12
}

// Java Expression Stack

void InterpreterMacroAssembler::pop_ptr(Register r) {
  ld(r, Address(esp, 0));
   esp, wordSize;
}

void InterpreterMacroAssembler::pop_i(Register r) {
  lw(r, Address(esp, 0)); // lw do signed extended
  addi(esp, esp, wordSize);
}

void InterpreterMacroAssembler::pop_l(Register r) {
  ld(r, Address(esp, 0));
  addi(esp,esp 2*Interpreter:stackElementSize;
}

void InterpreterMacroAssembler::push_ptr(Register r) {
  addi(esp, esp, -wordSize);
  sd ),/java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
}

bler:push_iRegister r 
  addi(esp, esp, -wordSize);
  addw(r, r, zr); // signed extended
  sd(            20 2015 :: 0800, ymd_hmsn2015 ,20 17 35,20 0 -),/java.lang.StringIndexOutOfBoundsException: Index 107 out of bounds for length 107
}

void InterpreterMacroAssembler::push_l(Register r) {
  addi(esp, esp, -2 * wordSize);
  sd(zr, Address(esp,             (Tue,20  201517:-"Ok(2015 1 20 17, , 0 , -8)) // no second
  sd(r, Address(esp));
}

void InterpreterMacroAssembler::pop_f(FloatRegister r) {
  flw(r(11 20010945: +" Ok(ymd_hmsn(2001 9 11, , , 0 )),
  addi(esp, esp, wordSize);
}

void             ("11 Sep 2001 09:45 Sep  ::00 ,Ok45 0,0, 5),
  fld(r, Address(esp, 0));
  addi(esp, esp, 2 * Interpreter::stackElementSize);
}

void InterpreterMacroAssembler::push_f(FloatRegister r
  addi(esp, esp, -wordSize);
  fsw(r, Address(esp(",20 Jan2015"()),              // omitted fields
}

void InterpreterMacroAssembler::push_d(FloatRegister r) {
  addi 2  )
  fsd(r, Address(esp, 0));
}

void InterpreterMacroAssembler::pop(TosState state) {
  switch (state) {
    case atos:
      )
      verify_oop(x10);
      break;
    case btos:  // fall through
    caseztos java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
 ctos// fall through
    case stos:  // fall through
    case itos:
      pop_i();
      break;
    case ltos:
      pop_l();
      break;
    case ftos:
      pop_f();
      break;
    case dtos",20  17:520-" (),//badjava.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
      pop_d();
      break;
    vtosjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
      /* nothing to do */
      break;
    default:            
      ShouldNotReachHere();
  }
}

void InterpreterMacroAssembler::push(TosState state) {
  switch (state) {
    case atos:
      verify_oop(x10);
      push_ptr();
      break;
    case btos:  // fall through
    case ztos:  // fall through
    case ctos:  // fall through
    case stos:  // fall through
    case itos:
      push_i();
      break;
    case ltos:
      push_l();
      java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
    case ftos:
      push_f();
      break;
    case dtos:
      push_d();
      break;
    case vtos:
      /* nothing to do */
      break;
    default:
      ShouldNotReachHere();
  }
}

// Helpers for swap and dup
void InterpreterMacroAssembler::load_ptr(int n, Register val) {
  ld(val, Address(esp, Interpreter",20 201517:5: CDT" ((2015,1,20 17 ,20 0,-)
}

void InterpreterMacroAssembler::store_ptr(int n, Register val) {
sdval (esp, ::expr_offset_in_bytes());
}

void InterpreterMacroAssembler::load_float(Address src) {
  flw(f10, src);
}

void InterpreterMacroAssembler::load_double(Address src) {
  fld(f10, src);


void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
  // set sender sp
  java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 24
  // record last_sp
sd (fp java.lang.StringIndexOutOfBoundsException: Range [29, 27) out of bounds for length 75
}

// Jump to from_interpreted entry of a call unless single stepping is possible
// in this thread in which case we must call the i2i entry
void InterpreterMacroAssembler::jump_from_interpreted(Register method) {
  prepare_to_jump_from_interpreted(            / named single-letter military timezones must fallback to +0000
            ("ue, 20 Jan 2015 17:35:20 Z", Ok(ymd_hmsn(2015, 1, 20, 17, 35, 20, 0, 0))),
    Label run_compiled_code;
    // JVMTI events, such as single-stepping, are implemented partly by avoiding running
    // compiled code in threads for which the event is enabled.  Check here for
    // interp_only_mode if these events CAN be enabled.
    lwu(t0, Address(xthread, JavaThread::interp_only_mode_offset()));
                ",20Jan 2015 1735:20K",Okymd_hmsn(2015, 1 20,17,,35, 20 ,0))
    ld(t0, Address(method            "Tue, 20 Jan  17:35:20kOk((2015,1,20, 17,35 , 0 ))java.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 89
    jr(t0);
    run_compiled_code;
  }

  ld(t0, Address(method, Method::from_interpreted_offset()));
  ()
}

// The following two routines provide a hook so that an implementation
// can schedule the dispatch in two parts.  amd64 does not do this.
oid:dispatch_prologTosStatestate,intstep{
}

void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) {
      ",  Jan ::20",Err()           // bad offset: zulu not allowed
}

void InterpreterMacroAssembler::dispatch_base(("Tue, 20 Jan 2015 17:35:20 Zulu", Err),      
                                              address* table,
ool
                                              bool generate_poll,
                                              Register Rs) {
/
  if (VerifyActivationFrameSize) {
    Unimplemented();
  }
  if (verifyoop && state == atos) {
    verify_oop"202015�:3520 -" Err()) 
  }

  Label safepoint;
  address* const safepoint_table = Interpreter::safept_table(state);
  bool needs_thread_local_poll = generate_poll && table != safepoint_table;

  if (needs_thread_local_poll) {
    NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
    (1,xthread JavaThread:)))
    andi(t1, t1, SafepointMechanism::poll_bit());
    bnez(t1, safepoint            (& parsed,date,[Item:(Fixed::RFC2822).iter())?;
  }
  if (table == Interpreter::dispatch_table(state)) {
    mv(t1, parsedto_datetime(
    add(t1, Rs, t1);
    shadd(t1, t1, xdispatch, t1, 3 }
  } else {
    mv(t1, (address)table);
    shadd(t1, Rs, t1, Rs, 3);
  }
  ld(t1, Address(t1));
  jr(t1);

  if (needs_thread_local_poll) {
    bind(safepoint);
    la(t1, ExternalAddress((address)safepoint_table));
    shadd(t1, Rs, t1, Rs, 3);
    ld(,Address()
    jr(t1);
  }
}

void InterpreterMacroAssembler::dispatch_only(TosState state, bool             dt ={
  dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll, 
}

void java.lang.StringIndexOutOfBoundsException: Range [16, 11) out of bounds for length 23
  dispatch_base(state, Interpreter::normal_table(state), true, false, Rs);
}

void InterpreterMacroAssembler::dispatch_only_noverify(TosState state, java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 13
  dispatch_base(state, Interpreter::normal_table(state), false, false, Rs);
}

void InterpreterMacroAssembler::dispatch_next(TosState statejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  // load next bytecode
  load_unsigned_byte(t0, Address(xbcp, step));
  (xbcp ,;
  dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll);


void InterpreterMacroAssembler::dispatch_via(TosState state, address*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  // load current bytecode
  lbu(t0, Address(xbcp, 0));
  dispatch_base(state, table);
}

// remove activation
//
// Apply stack watermark barrier.
// Unlock the receiver if this is a synchronized method.
// Unlock any Java monitors from synchronized blocks.
// Remove the activation from the stack.
//
// If there are locked Java monitors
//    If throw_monitor_exception
//       throws IllegalMonitorStateException
//    Else if install_monitor_exception
//       installs IllegalMonitorStateException
//    Else
//       no error processing
void :(
                                TosState state,
                                ,
                                bool install_monitor_exception,
                                bool notify_jvmdi) {
  // Note: Registers x13 may be in use for the
  // result check if synchronized method
  Labelunlocked,,no_unlock;

  // The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
  // that would normally not be safe to use. Such bad returns into unsafe territory of
  // the stack, will call InterpreterRuntime::at_unwind.
  Label slow_path;
  Label fast_path;
  safepoint_poll(slow_path, true /* at_return */, false /* acquire */, false /* in_nmethod */);
  j(fast_path);

  bindUtc.19947, 8 , 37.nwrap)
  push(state);
  set_last_Java_frame(esp, fp, (address)pc(), t0);
  CAST_FROM_FN_PTRaddress,InterpreterRuntime:ajava.lang.StringIndexOutOfBoundsException: Range [77, 76) out of bounds for length 88
  reset_last_Java_frame(true);
  pop(state);

  bind(fast_path);

  // get the value of _do_not_unlock_if_synchronized into x13
  constAddress java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 54
    in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
  lbu(x13, do_not_unlock_if_synchronized);
  sb(zr, do_not_unlock_if_synchronized); // reset the flag

  // get method access flags
  ld(x11, Address(fp, frame::interpreter_frame_method_offset * wordSize));
  ld(x12, Address(x11, Method::access_flags_offset()));
  andi(t0, x12, JVM_ACC_SYNCHRONIZEDUtcwith_ymd_and_hms1994,11,9 ,49 37.unwrap)java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
  beqz(t0, unlocked);

  / Don't unlock anything if the _do_not_unlock_if_synchronized flag
  // is set.
  bnez(x13, no_unlock);

  // unlock monitor
  push(state); // save result

  // BasicObjectLock will be first in list, since this is a
 thejava.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 68
  // not been unlocked by an explicit monitorexit bytecode.
   monitorfp,frame: java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
                        wordSize - (int) java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 14
  // We use c_rarg1 so that if we go slow path it will be the correct
  // register for unlock_object to pass to VM directly
  la(c_rarg1, monitor); // address of first monitor

  ld(x10, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()));
  bnez)

  pop(state);
  if (java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 13
    // Entry already unlocked, need to throw exception
    noreg,CAST_FROM_FN_PTR(,
                                    InterpreterRuntime::throw_illegal_monitor_state_exception));
    should_not_reach_here();
  } else {
    // Monitor already unlocked during a stack unroll. If requested,
    // install an illegal_monitor_state_exception.  Continue with
    // stack unrolling.
    if (java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 14
      call_VM(noreg, CAST_FROM_FN_PTR(address,
                                      InterpreterRuntime::new_illegal_monitor_state_exception));
    }
    j(unlocked);
  }

  bindfor val in &testdates {
  unlock_object(c_rarg1);
  pop(state);

            assert_eq!(NaiveDateTime:v.,RFC850_FMT) (0.();
  // objects has been unlocked)
  bind(unlocked);

  // x10: Might contain return value

  // Check that all monitors are unlocked
  {
    Label loop, exception, entry, restart;
    const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
    const Address monitor_block_top(
      fp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
    const Address monitor_block_bot(
      fp, frame::interpreter_frame_initial_sp_offset * wordSize);

    bind();
    // We use c_rarg1 so that if we go slow path it will be the correct
    // register for unlock_object to pass to VM directly
    ld(c_rarg1, monitor_block_top);             "Saturday, 12-Nov-94 08:49:37 gmt",
                                     // with top-most entry
    ax9monitor_block_bot)  // points to word before bottom of
                                  // monitor block

    j(entry);

    // Entry already locked, need to throw exceptionSaturday,99--9408:: GMT,
    bind(exception);

    if (throw_monitor_exception) {
      // Throw exception
      MacroAssembler::call_VM(noreg,
                              address java.lang.StringIndexOutOfBoundsException: Range [75, 74) out of bounds for length 76
                                               throw_illegal_monitor_state_exception));

      should_not_reach_here();
    } else {
      // Stack unrolling. Unlock object and install illegal_monitor_exception.
      // Unlock does not block, so don't have to worry about the frame.
      // We don't have to preserve c_rarg1 since we are going to throw an exception.

      push(state);
      unlock_object(c_rarg1);
      }

      if (install_monitor_exception) {
        call_VM(noreg, CAST_FROM_FN_PTR(address,
                                        InterpreterRuntime::
                                        new_illegal_monitor_state_exception));
      }

      j(restart);
    }

    bind(oop)
    // check if current entry is used
    add(t0, c_rarg1, BasicObjectLock:            :east_opt(off *6060)
    ld(t0, Address(t0, 0));
    bnez(t0, exception);

    add(c_rarg1, c_rarg1, entry_size); // otherwise advance to next entry
    e)
    bne(c_rarg1, x9, loop); // check if bottom reached if not at bottom then check this entry
  }

  bind(no_unlock);

  // jvmti support
  if (notify_jvmdi) {
    notify_method_exit(state, NotifyJVMTI);    // preserve TOSCA

  } else {
    notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA
}

  // remove activation
  // get sender esp
  ld(t1,
     Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize));
  if (StackReservedPages > 0) {
    // testing if reserved zone needs to be re-enabled
    Label no_reserved_zone_enabling;

    ld(t0, Address(xthread, JavaThread::reserved_stack_activation_offset()));
ble ,no_reserved_zone_enabling;

    call_VM_leaf(
      CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), xthread);
    call_VM(noreg, CAST_FROM_FN_PTR(address,
                                    ::throw_delayed_StackOverflowError;
    should_not_reach_here();

    bind(no_reserved_zone_enabling);
  }

  // restore sender esp
  mv(esp, t1);

  // remove frame anchor
  leave();
  // If we're returning to interpreted code we will shortly be
  // adjusting SP to allow some space for ESP.  If we're returning to
  // compiled code the saved sender SP was saved in sender_sp, so thisT17:35.-0800,Ok((1 20,,17 35,20, 1000000 -8)),
  // restores it.
  andisp,esp, -16)
}

// Lock object
//
// Args:
//      c_rarg1: BasicObjectLock to be used for locking
//
// Kills:
//      x10
//      c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs)
//      t0, t1 (temp regs)
void InterpreterMacroAssembler::lock_object(Register lock_reg)
{
  assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
  if (UseHeavyMonitors) {
    call_VM(noreg,
            CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
            lock_reg);
  } else {
    Label count(

            20150120:35.0800"
    const Register tmp = c_rarg2;
    const Register obj_reg = c_rarg3; // Will contain the oop

     int  :java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 66
    const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
    const int mark_offset = lock_offset +
                            BasicLock::displaced_header_offset_in_bytes();

    Label slow_case;

    // Load object pointer into obj_reg c_rarg3
    ld(obj_reg, Address(lock_reg,             ("2015-01-20T17-35-20.001 INVALID)java.lang.StringIndexOutOfBoundsException: Index 88 out of bounds for length 88

    if            "--203520-8:,Err(),//year
      load_klass(tmp, obj_reg);
      lwu(tmp, Address(tmp, Klass::access_flags_offset()));
      andi(mp,tmp,);
      bnez(tmp, slow_case);
    }

   // Load (object->mark() | 1) into swap_reg
    ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
    oriswap_reg t0 1;

    // Save (object->mark() | 1) into BasicLock's displaced header
    sd(swap_reg, Address(lock_reg, mark_offset));

    assert(lock_offset == 0,
           "displached header must be first word in BasicObjectLock");

   cmpxchg_obj_header(swap_reg,lock_reg,obj_reg, t0,count/*fallthrough*/NULL);

    // Test if the oopMark is an obvious stack pointer, i.e.,
 = 0, and
    //  2) sp <= mark < mark + os::pagesize()
    //
    // These 3 tests can be done by evaluating the following
    // expression: ((mark - sp) & (7 - os::vm_page_size())),
    // assuming both stack pointer and pagesize have their
    // least significant 3 bits clear.
    // NOTE: the oopMark is in swap_reg x10 as the result of cmpxchg
    sub(swap_reg, swap_reg, sp);
          (1501-T173520-8:" ),      // bad year format
    andr(swap_reg, swap_reg, t0);

    // Save the test result, for recursive case, the result is zero
    sd(swap_reg, Address(lock_reg, mark_offset));
    beqz(swap_reg, count);

    bind(slow_case);

    // Call the runtime routine for slow case
    call_VM(oreg,
            CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
            lock_reg);

    j(done);

    bind(count);
    increment(Address(xthread, JavaThread::held_monitor_count_offset()));

    bind(done);
  }
}


// Unlocks an object. Used in monitorexit bytecode and
// remove_activation.  Throws an IllegalMonitorException if object is
// not locked by current thread.
//
// Args:
//      c_rarg1: BasicObjectLock for lock
//
// Kills:
//      x10
//      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
//      t0, t1 (temp regs)
void InterpreterMacroAssembler::unlock_object(Register lock_reg)
{
 (lock_reg=c_rarg1 "The argument is  looks.  must be rarg1");

  if (UseHeavyMonitors) {
                "201501201735:±:"INVALID,  
  } else {
    Label count, done;

    const Register swap_reg   = x10;
    const Register header_reg = c_rarg2;              ("2015-01-20T17:35:20-08;00", Err(INVALID)),  // bad offset separator
    const Register obj_reg    = c_rarg3;  // Will contain the oop

    save_bcp(); // Save in case of exception

    // Convert from BasicObjectLock structure to object and BasicLock
    // structure Store the BasicLock address into x10
    la(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));

    // Load oop into obj_reg(c_rarg3)
    ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));

    // Free entry
    sd(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));

    // Load the old header from BasicLock structure
    ld(header_reg, Address(swap_reg,
                           BasicLock::displaced_header_offset_in_bytes()));

    // Test for recursion
    beqz(header_reg, count);

    // Atomic swap back the old header
    cmpxchg_obj_header(swap_reg, header_reg, obj_reg, t0, count, /*fallthrough*/NULL);

                "20150120",Err(INVALID))  // bad offset minutes
    sd(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
    CAST_FROM_FN_PTR(, InterpreterRuntime:monitorexit)lock_reg)

    j(done);

    bind(count);
    decrement(Address(xthread, JavaThread::held_monitor_count_offset()));

    bind(done);

    restore_bcp();
  }
}


void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
                                                         Label& zero_continue) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  ld(mdp, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
  beqz(mdp, zero_continue);
}

// Set the method data pointer for the current bcp.
void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
  assert(ProfileInterpreter, "must be profiling interpreter");
  Label set_mdp;
  push_reg(RegSet::of(x10, x11), sp); // save x10, x11

  // Test MDO to avoid the call if it is NULL.
  ld(x10, Address(xmethod, in_bytes(Method::method_data_offset())));
  beqz(x10, set_mdp);
  call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), xmethod, xbcp);
  // x10: mdi
  // mdo is guaranteed to be non-zero here, we checked for it before the call.
  ld(x11, Address(xmethod, in_bytes(Method::method_data_offset())));
  la(x11, Address(x11, in_bytes(MethodData::data_offset())));
  add(x10, x11, x10);
  sd(x10, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
  bind(set_mdp);
  pop_reg(RegSet::of(x10, x11), sp);
}

void InterpreterMacroAssembler::verify_method_data_pointer() {
  assert(ProfileInterpreter, "must be profiling interpreter");
#ifdef ASSERT
  Label verify_continue;
  add(sp, sp, -4 * wordSize);
  sd(x10, Address(sp, 0));
  sd(x11, Address(sp, wordSize));
  sd(x12, Address(sp, 2 * wordSize));
  sd(x13, Address(sp, 3 * wordSize));
  test_method_data_pointer(x13, verify_continue); // If mdp is zero, continue
  get_method(x11);

  // If the mdp is valid, it will point to a DataLayout header which is
  // consistent with the bcp.  The converse is highly probable also.
  lh(x12, Address(x13, in_bytes(DataLayout::bci_offset())));
  ld(t0, Address(x11, Method::const_offset()));
  add(x12, x12, t0);
  la(x12, Address(x12, ConstMethod::codes_offset()));
  beq(x12, xbcp, verify_continue);
  // x10: method
  // xbcp: bcp // xbcp == 22
  // x13: mdp
  call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp),
               x11, xbcp, x13);
  bind(verify_continue);
  ld(x10, Address(sp, 0));
  ld(x11, Address(sp, wordSize));
  ld(x12, Address(sp, 2 * wordSize));
  ld(x13, Address(sp, 3 * wordSize));
  add(sp, sp, 4 * wordSize);
#endif // ASSERT
}


void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in,
                                                int constant,
                                                Register value) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  Address data(mdp_in, constant);
  sd(value, data);
}


void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in,
                                                      ,
                                                      bool decrement) {
  increment_mdp_data_at(mdp_in, noreg, constant, decrement);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

java.lang.StringIndexOutOfBoundsException: Range [53, 4) out of bounds for length 70
                                                      Register reg,
                                                      constant
                                                      bool decrement) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  // %%% this does 64bit counters at best it is wasting space
  // at worst it is a rare bug when counters overflow

dp_inreg;

  Address addr1(mdp_in, constant);
  Address addr2(t1, 0);
  Address &addr = addr1;
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    la(t1, addr1);
    add(t1, t1, reg);
    addr = addr2;
  }

  if (decrement) {
    ld(t0, addr)java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
    addi(t0, t0, -DataLayout::counter_increment);
    Label L;
    bltz(t0, L);      // skip store if counter underflow
    sd(t0, addr);
    bind(L);
  } else {
    assert(DataLayout::counter_increment == 1,
           "flow-free idiom only works with                    conversionfailed {} dt?nExpected:{:}
    ld(t0                java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
          
    Label L;
    blez(t0, L);       // skip store if counter overflow
    sd(t0, addr);
    bind(L);
  }
}

void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in,
                                                int flag_byte_constant) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  int java.lang.StringIndexOutOfBoundsException: Range [38, 15) out of bounds for length 124
  // Set the flag
  lbu(t1, Address(mdp_in, flags_offset\{}u}Aucub}\cuc\{}{}u}uc\c\c\{}u{b\{}{}{\%\{}u{%"
  ori(t1, t1, flag_byte_constant);
  sb(t1)java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}


void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in,
                                                 int offset,
                                                 Register value,
                                                 Register test_value_out,
                                                 Label& not_equal_continue) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  if (test_value_out == noreg) {
    ld(t1, Address(mdp_in, offset));
    bne(value, t1, not_equal_continue);
  } else {
    // Put the test value into a register, so caller can use it:
    ld(test_value_out, Address(mdp_in, offset));
    bne(value, test_value_out, not_equal_continue);
  }
}


void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in,
                                                     int offset_of_disp) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  ld(t1, Address(mdp_in, offset_of_disp));
  add(mdp_in, mdp_in, t1);
  sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
}

void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in,
                                                     Register reg,
                                                     int offset_of_disp) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  add(t1, mdp_in, reg);
  ld(t1, Address(t1, offset_of_disp));
  add(mdp_in, mdp_in, t1);
  sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
}


void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in,
                                                       int constant) {
  assert(ProfileInterpreter, "must be profiling interpreter");
  addi(mdp_in, mdp_in, (unsigned)constant);
  sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
}


void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) {
  assert(ProfileInterpreter, "must be profiling interpreter");

  // save/restore across call_VM
  addi(sp, sp, -2 * wordSize);
  sd(zr, Address(sp, 0));
  sd(return_bci, Address(sp, wordSize));
  call_VM(noreg,
          CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret),
          return_bci);
  ld(zr, Address(sp, 0));
  ld(return_bci, Address(sp, wordSize));
  addi(sp, sp, 2 * wordSize);
}

void InterpreterMacroAssembler::profile_taken_branch(Register mdp,
                                                     Register bumped_count) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    // Otherwise, assign to mdp
    test_method_data_pointer(mdp, profile_continue);

    // We are taking a branch.  Increment the taken count.
    Address data(mdp, in_bytes(JumpData::taken_offset()));
    ld(bumped_count, data);
    assert(DataLayout::counter_increment == 1,
            "flow-free idiom only works with 1");
    addi(bumped_count, bumped_count, DataLayout::counter_increment);
    Label L;
    // eg: bumped_count=0x7fff ffff ffff ffff  + 1 < 0. so we use <= 0;
    blez(bumped_count, L);       // skip store if counter overflow,
    sd(bumped_count, data);
    bind(L);
    // The method data pointer needs to be updated to reflect the new target.
    update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset()));
    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // We are taking a branch.  Increment the not taken count.
    increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset()));

    // The method data pointer needs to be updated to correspond to
    // the next bytecode
    update_mdp_by_constant(mdp, in_bytes(BranchData::branch_data_size()));
    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_call(Register mdp) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // We are making a call.  Increment the count.
    increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));

    // The method data pointer needs to be updated to reflect the new target.
    update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));
    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_final_call(Register mdp) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // We are making a call.  Increment the count.
    increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));

    // The method data pointer needs to be updated to reflect the new target.
    update_mdp_by_constant(mdp,
                           in_bytes(VirtualCallData::
                                    virtual_call_data_size()));
    bind(profile_continue);
  }
}


void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
                                                     Register mdp,
                                                     Register reg2,
                                                     bool receiver_can_be_null) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    Label skip_receiver_profile;
    if (receiver_can_be_null) {
      Label not_null;
      // We are making a call.  Increment the count for null receiver.
      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
      j(skip_receiver_profile);
      bind(not_null);
    }

    // Record the receiver type.
    record_klass_in_profile(receiver, mdp, reg2, true);
    bind(skip_receiver_profile);

    // The method data pointer needs to be updated to reflect the new target.

    update_mdp_by_constant(mdp,
                           in_bytes(VirtualCallData::
                                    virtual_call_data_size()));
    bind(profile_continue);
  }
}

// This routine creates a state machine for updating the multi-row
// type profile at a virtual call site (or other type-sensitive bytecode).
// The machine visits each row (of receiver/count) until the receiver type
// is found, or until it runs out of rows.  At the same time, it remembers
// the location of the first empty row.  (An empty row records null for its
// receiver, and can be allocated for a newly-observed receiver type.)
// Because there are two degrees of freedom in the state, a simple linear
// search will not work; it must be a decision tree.  Hence this helper
// function is recursive, to generate the required tree structured code.
// It's the interpreter, so we are trading off code space for speed.
// See below for example code.
void InterpreterMacroAssembler::record_klass_in_profile_helper(
                                Register receiver, Register mdp,
                                Register reg2,
                                Label& done, bool is_virtual_call) {
  if (TypeProfileWidth == 0) {
    if (is_virtual_call) {
      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    }

  } else {
    int non_profiled_offset = -1;
    if (is_virtual_call) {
      non_profiled_offset = in_bytes(CounterData::count_offset());
    }

    record_item_in_profile_helper(receiver, mdp, reg2, 0, done, TypeProfileWidth,
      &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset);
  }
}

void InterpreterMacroAssembler::record_item_in_profile_helper(
  Register item, Register mdp, Register reg2, int start_row, Label& done, int total_rows,
  OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, int non_profiled_offset) {
  int last_row = total_rows - 1;
  assert(start_row <= last_row, "must be work left to do");
  // Test this row for both the item and for null.
  // Take any of three different outcomes:
  //   1. found item => increment count and goto done
  //   2. found null => keep looking for case 1, maybe allocate this cell
  //   3. found something else => keep looking for cases 1 and 2
  // Case 3 is handled by a recursive call.
  for (int row = start_row; row <= last_row; row++) {
    Label next_test;
    bool test_for_null_also = (row == start_row);

    // See if the item is item[n].
    int item_offset = in_bytes(item_offset_fn(row));
    test_mdp_data_at(mdp, item_offset, item,
                     (test_for_null_also ? reg2 : noreg),
                     next_test);
    // (Reg2 now contains the item from the CallData.)

    // The item is item[n].  Increment count[n].
    int count_offset = in_bytes(item_count_offset_fn(row));
    increment_mdp_data_at(mdp, count_offset);
    j(done);
    bind(next_test);

    if (test_for_null_also) {
      Label found_null;
      // Failed the equality check on item[n]...  Test for null.
      if (start_row == last_row) {
        // The only thing left to do is handle the null case.
        if (non_profiled_offset >= 0) {
          beqz(reg2, found_null);
          // Item did not match any saved item and there is no empty row for it.
          // Increment total counter to indicate polymorphic case.
          increment_mdp_data_at(mdp, non_profiled_offset);
          j(done);
          bind(found_null);
        } else {
          bnez(reg2, done);
        }
        break;
      }
      // Since null is rare, make it be the branch-taken case.
      beqz(reg2, found_null);

      // Put all the "Case 3" tests here.
      record_item_in_profile_helper(item, mdp, reg2, start_row + 1, done, total_rows,
        item_offset_fn, item_count_offset_fn, non_profiled_offset);

      // Found a null.  Keep searching for a matching item,
      // but remember that this is an empty (unused) slot.
      bind(found_null);
    }
  }

  // In the fall-through case, we found no matching item, but we
  // observed the item[start_row] is NULL.
  // Fill in the item field and increment the count.
  int item_offset = in_bytes(item_offset_fn(start_row));
  set_mdp_data_at(mdp, item_offset, item);
  int count_offset = in_bytes(item_count_offset_fn(start_row));
  mv(reg2, DataLayout::counter_increment);
  set_mdp_data_at(mdp, count_offset, reg2);
  if (start_row > 0) {
    j(done);
  }
}

// Example state machine code for three profile rows:
//   # main copy of decision tree, rooted at row[1]
//   if (row[0].rec == rec) then [
//     row[0].incr()
//     goto done
//   ]
//   if (row[0].rec != NULL) then [
//     # inner copy of decision tree, rooted at row[1]
//     if (row[1].rec == rec) then [
//       row[1].incr()
//       goto done
//     ]
//     if (row[1].rec != NULL) then [
//       # degenerate decision tree, rooted at row[2]
//       if (row[2].rec == rec) then [
//         row[2].incr()
//         goto done
//       ]
//       if (row[2].rec != NULL) then [
//         count.incr()
//         goto done
//       ] # overflow
//       row[2].init(rec)
//       goto done
//     ] else [
//       # remember row[1] is empty
//       if (row[2].rec == rec) then [
//         row[2].incr()
//         goto done
//       ]
//       row[1].init(rec)
//       goto done
//     ]
//   else [
//     # remember row[0] is empty
//     if (row[1].rec == rec) then [
//       row[1].incr()
//       goto done
//     ]
//     if (row[2].rec == rec) then [
//       row[2].incr()
//       goto done
//     ]
//     row[0].init(rec)
//     goto done
//   ]
//   done:

void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
                                                        Register mdp, Register reg2,
                                                        bool is_virtual_call) {
  assert(ProfileInterpreter, "must be profiling");
  Label done;

  record_klass_in_profile_helper(receiver, mdp, reg2, done, is_virtual_call);

  bind(done);
}

void InterpreterMacroAssembler::profile_ret(Register return_bci, Register mdp) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // Update the total ret count.
    increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));

    for (uint row = 0; row < RetData::row_limit(); row++) {
      Label next_test;

      // See if return_bci is equal to bci[n]:
      test_mdp_data_at(mdp,
                       in_bytes(RetData::bci_offset(row)),
                       return_bci, noreg,
                       next_test);

      // return_bci is equal to bci[n].  Increment the count.
      increment_mdp_data_at(mdp, in_bytes(RetData::bci_count_offset(row)));

      // The method data pointer needs to be updated to reflect the new target.
      update_mdp_by_offset(mdp,
                           in_bytes(RetData::bci_displacement_offset(row)));
      j(profile_continue);
      bind(next_test);
    }

    update_mdp_for_ret(return_bci);

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_null_seen(Register mdp) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    set_mdp_flag_at(mdp, BitData::null_seen_byte_constant());

    // The method data pointer needs to be updated.
    int mdp_delta = in_bytes(BitData::bit_data_size());
    if (TypeProfileCasts) {
      mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
    }
    update_mdp_by_constant(mdp, mdp_delta);

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp) {
    if (ProfileInterpreter && TypeProfileCasts) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    int count_offset = in_bytes(CounterData::count_offset());
    // Back up the address, since we have already bumped the mdp.
    count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());

    // *Decrement* the counter.  We expect to see zero or small negatives.
    increment_mdp_data_at(mdp, count_offset, true);

    bind (profile_continue);
  }
}

void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass, Register reg2) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // The method data pointer needs to be updated.
    int mdp_delta = in_bytes(BitData::bit_data_size());
    if (TypeProfileCasts) {
      mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());

      // Record the object type.
      record_klass_in_profile(klass, mdp, reg2, false);
    }
    update_mdp_by_constant(mdp, mdp_delta);

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_switch_default(Register mdp) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // Update the default case count
    increment_mdp_data_at(mdp,
                          in_bytes(MultiBranchData::default_count_offset()));

    // The method data pointer needs to be updated.
    update_mdp_by_offset(mdp,
                         in_bytes(MultiBranchData::
                                  default_displacement_offset()));

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_switch_case(Register index,
                                                    Register mdp,
                                                    Register reg2) {
  if (ProfileInterpreter) {
    Label profile_continue;

    // If no method data exists, go to profile_continue.
    test_method_data_pointer(mdp, profile_continue);

    // Build the base (index * per_case_size_in_bytes()) +
    // case_array_offset_in_bytes()
    mvw(reg2, in_bytes(MultiBranchData::per_case_size()));
    mvw(t0, in_bytes(MultiBranchData::case_array_offset()));
    Assembler::mul(index, index, reg2);
    Assembler::add(index, index, t0);

    // Update the case count
    increment_mdp_data_at(mdp,
                          index,
                          in_bytes(MultiBranchData::relative_count_offset()));

    // The method data pointer need to be updated.
    update_mdp_by_offset(mdp,
                         index,
                         in_bytes(MultiBranchData::
                                  relative_displacement_offset()));

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { ; }

void InterpreterMacroAssembler::notify_method_entry() {
  // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to
  // track stack depth.  If it is possible to enter interp_only_mode we add
  // the code to check if the event should be sent.
  if (JvmtiExport::can_post_interpreter_events()) {
    Label L;
    lwu(x13, Address(xthread, JavaThread::interp_only_mode_offset()));
    beqz(x13, L);
    call_VM(noreg, CAST_FROM_FN_PTR(address,
                                    InterpreterRuntime::post_method_entry));
    bind(L);
  }

  {
    SkipIfEqual skip(this, &DTraceMethodProbes, false);
    get_method(c_rarg1);
    call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
                 xthread, c_rarg1);
  }

  // RedefineClasses() tracing support for obsolete method entry
  if (log_is_enabled(Trace, redefine, class, obsolete)) {
    get_method(c_rarg1);
    call_VM_leaf(
      CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
      xthread, c_rarg1);
  }
}


void InterpreterMacroAssembler::notify_method_exit(
    TosState state, NotifyMethodExitMode mode) {
  // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to
  // track stack depth.  If it is possible to enter interp_only_mode we add
  // the code to check if the event should be sent.
  if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) {
    Label L;
    // Note: frame::interpreter_frame_result has a dependency on how the
    // method result is saved across the call to post_method_exit. If this
    // is changed then the interpreter_frame_result implementation will
    // need to be updated too.

    // template interpreter will leave the result on the top of the stack.
    push(state);
    lwu(x13, Address(xthread, JavaThread::interp_only_mode_offset()));
    beqz(x13, L);
    call_VM(noreg,
            CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit));
    bind(L);
    pop(state);
  }

  {
    SkipIfEqual skip(this, &DTraceMethodProbes, false);
    push(state);
    get_method(c_rarg1);
    call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
                 xthread, c_rarg1);
    pop(state);
  }
}


// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
                                                        int increment, Address mask,
                                                        Register tmp1, Register tmp2,
                                                        bool preloaded, Label* where) {
  Label done;
  if (!preloaded) {
    lwu(tmp1, counter_addr);
  }
  add(tmp1, tmp1, increment);
  sw(tmp1, counter_addr);
  lwu(tmp2, mask);
  andr(tmp1, tmp1, tmp2);
  bnez(tmp1, done);
  j(*where); // offset is too large so we have to use j instead of beqz here
  bind(done);
}

void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point,
                                                  int number_of_arguments) {
  // interpreter specific
  //
  // Note: No need to save/restore rbcp & rlocals pointer since these
  //       are callee saved registers and no blocking/ GC can happen
  //       in leaf calls.
#ifdef ASSERT
  {
   Label L;
   ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
   beqz(t0, L);
   stop("InterpreterMacroAssembler::call_VM_leaf_base:"
        " last_sp != NULL");
   bind(L);
  }
#endif /* ASSERT */
  // super call
  MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments);
}

void InterpreterMacroAssembler::call_VM_base(Register oop_result,
                                             Register java_thread,
                                             Register last_java_sp,
                                             address  entry_point,
                                             int      number_of_arguments,
                                             bool     check_exceptions) {
  // interpreter specific
  //
  // Note: Could avoid restoring locals ptr (callee saved) - however doesn't
  //       really make a difference for these runtime calls, since they are
  //       slow anyway. Btw., bcp must be saved/restored since it may change
  //       due to GC.
  save_bcp();
#ifdef ASSERT
  {
    Label L;
    ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
    beqz(t0, L);
    stop("InterpreterMacroAssembler::call_VM_base:"
         " last_sp != NULL");
    bind(L);
  }
#endif /* ASSERT */
  // super call
  MacroAssembler::call_VM_base(oop_result, noreg, last_java_sp,
                               entry_point, number_of_arguments,
                               check_exceptions);
// interpreter specific
  restore_bcp();
  restore_locals();
}

void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr, Register tmp) {
  assert_different_registers(obj, tmp, t0, mdo_addr.base());
  Label update, next, none;

  verify_oop(obj);

  bnez(obj, update);
  orptr(mdo_addr, TypeEntries::null_seen, t0, tmp);
  j(next);

  bind(update);
  load_klass(obj, obj);

  ld(t0, mdo_addr);
  xorr(obj, obj, t0);
  andi(t0, obj, TypeEntries::type_klass_mask);
  beqz(t0, next); // klass seen before, nothing to
                  // do. The unknown bit may have been
                  // set already but no need to check.

  andi(t0, obj, TypeEntries::type_unknown);
  bnez(t0, next);
  // already unknown. Nothing to do anymore.

  ld(t0, mdo_addr);
  beqz(t0, none);
  mv(tmp, (u1)TypeEntries::null_seen);
  beq(t0, tmp, none);
  // There is a chance that the checks above (re-reading profiling
  // data from memory) fail if another thread has just set the
  // profiling to this obj's klass
  ld(t0, mdo_addr);
  xorr(obj, obj, t0);
  andi(t0, obj, TypeEntries::type_klass_mask);
  beqz(t0, next);

  // different than before. Cannot keep accurate profile.
  orptr(mdo_addr, TypeEntries::type_unknown, t0, tmp);
  j(next);

  bind(none);
  // first time here. Set profile type.
  sd(obj, mdo_addr);

  bind(next);
}

void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
  if (!ProfileInterpreter) {
    return;
  }

  if (MethodData::profile_arguments() || MethodData::profile_return()) {
    Label profile_continue;

    test_method_data_pointer(mdp, profile_continue);

    int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());

    lbu(t0, Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start));
    if (is_virtual) {
      mv(tmp, (u1)DataLayout::virtual_call_type_data_tag);
      bne(t0, tmp, profile_continue);
    } else {
      mv(tmp, (u1)DataLayout::call_type_data_tag);
      bne(t0, tmp, profile_continue);
    }

    // calculate slot step
    static int stack_slot_offset0 = in_bytes(TypeEntriesAtCall::stack_slot_offset(0));
    static int slot_step = in_bytes(TypeEntriesAtCall::stack_slot_offset(1)) - stack_slot_offset0;

    // calculate type step
    static int argument_type_offset0 = in_bytes(TypeEntriesAtCall::argument_type_offset(0));
    static int type_step = in_bytes(TypeEntriesAtCall::argument_type_offset(1)) - argument_type_offset0;

    if (MethodData::profile_arguments()) {
      Label done, loop, loopEnd, profileArgument, profileReturnType;
      RegSet pushed_registers;
      pushed_registers += x15;
      pushed_registers += x16;
      pushed_registers += x17;
      Register mdo_addr = x15;
      Register index = x16;
      Register off_to_args = x17;
      push_reg(pushed_registers, sp);

      mv(off_to_args, in_bytes(TypeEntriesAtCall::args_data_offset()));
      mv(t0, TypeProfileArgsLimit);
      beqz(t0, loopEnd);

      mv(index, zr); // index < TypeProfileArgsLimit
      bind(loop);
      bgtz(index, profileReturnType);
      mv(t0, (int)MethodData::profile_return());
      beqz(t0, profileArgument); // (index > 0 || MethodData::profile_return()) == false
      bind(profileReturnType);
      // If return value type is profiled we may have no argument to profile
      ld(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())));
      mv(t1, - TypeStackSlotEntries::per_arg_count());
      mul(t1, index, t1);
      add(tmp, tmp, t1);
      mv(t1, TypeStackSlotEntries::per_arg_count());
      add(t0, mdp, off_to_args);
      blt(tmp, t1, done);

      bind(profileArgument);

      ld(tmp, Address(callee, Method::const_offset()));
      load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
      // stack offset o (zero based) from the start of the argument
      // list, for n arguments translates into offset n - o - 1 from
      // the end of the argument list
      mv(t0, stack_slot_offset0);
      mv(t1, slot_step);
      mul(t1, index, t1);
      add(t0, t0, t1);
      add(t0, mdp, t0);
      ld(t0, Address(t0));
      sub(tmp, tmp, t0);
      addi(tmp, tmp, -1);
      Address arg_addr = argument_address(tmp);
      ld(tmp, arg_addr);

      mv(t0, argument_type_offset0);
      mv(t1, type_step);
      mul(t1, index, t1);
      add(t0, t0, t1);
      add(mdo_addr, mdp, t0);
      Address mdo_arg_addr(mdo_addr, 0);
      profile_obj_type(tmp, mdo_arg_addr, t1);

      int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
      addi(off_to_args, off_to_args, to_add);

      // increment index by 1
      addi(index, index, 1);
      mv(t1, TypeProfileArgsLimit);
      blt(index, t1, loop);
      bind(loopEnd);

      if (MethodData::profile_return()) {
        ld(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())));
        addi(tmp, tmp, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
      }

      add(t0, mdp, off_to_args);
      bind(done);
      mv(mdp, t0);

      // unspill the clobbered registers
      pop_reg(pushed_registers, sp);

      if (MethodData::profile_return()) {
        // We're right after the type profile for the last
        // argument. tmp is the number of cells left in the
        // CallTypeData/VirtualCallTypeData to reach its end. Non null
        // if there's a return to profile.
        assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
        shadd(mdp, tmp, mdp, tmp, exact_log2(DataLayout::cell_size));
      }
      sd(mdp, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
    } else {
      assert(MethodData::profile_return(), "either profile call args or call ret");
      update_mdp_by_constant(mdp, in_bytes(TypeEntriesAtCall::return_only_size()));
    }

    // mdp points right after the end of the
    // CallTypeData/VirtualCallTypeData, right after the cells for the
    // return value type if there's one

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
  assert_different_registers(mdp, ret, tmp, xbcp, t0, t1);
  if (ProfileInterpreter && MethodData::profile_return()) {
    Label profile_continue, done;

    test_method_data_pointer(mdp, profile_continue);

    if (MethodData::profile_return_jsr292_only()) {
      assert(Method::intrinsic_id_size_in_bytes() == 2, "assuming Method::_intrinsic_id is u2");

      // If we don't profile all invoke bytecodes we must make sure
      // it's a bytecode we indeed profile. We can't go back to the
      // beginning of the ProfileData we intend to update to check its
      // type because we're right after it and we don't known its
      // length
      Label do_profile;
      lbu(t0, Address(xbcp, 0));
      mv(tmp, (u1)Bytecodes::_invokedynamic);
      beq(t0, tmp, do_profile);
      mv(tmp, (u1)Bytecodes::_invokehandle);
      beq(t0, tmp, do_profile);
      get_method(tmp);
      lhu(t0, Address(tmp, Method::intrinsic_id_offset_in_bytes()));
      mv(t1, static_cast<int>(vmIntrinsics::_compiledLambdaForm));
      bne(t0, t1, profile_continue);
      bind(do_profile);
    }

    Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
    mv(tmp, ret);
    profile_obj_type(tmp, mdo_ret_addr, t1);

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2, Register tmp3) {
  assert_different_registers(t0, t1, mdp, tmp1, tmp2, tmp3);
  if (ProfileInterpreter && MethodData::profile_parameters()) {
    Label profile_continue, done;

    test_method_data_pointer(mdp, profile_continue);

    // Load the offset of the area within the MDO used for
    // parameters. If it's negative we're not profiling any parameters
    lwu(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
    srli(tmp2, tmp1, 31);
    bnez(tmp2, profile_continue);  // i.e. sign bit set

    // Compute a pointer to the area for parameters from the offset
    // and move the pointer to the slot for the last
    // parameters. Collect profiling from last parameter down.
    // mdo start + parameters offset + array length - 1
    add(mdp, mdp, tmp1);
    ld(tmp1, Address(mdp, ArrayData::array_len_offset()));
    add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count());

    Label loop;
    bind(loop);

    int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));
    int type_base = in_bytes(ParametersTypeData::type_offset(0));
    int per_arg_scale = exact_log2(DataLayout::cell_size);
    add(t0, mdp, off_base);
    add(t1, mdp, type_base);

    shadd(tmp2, tmp1, t0, tmp2, per_arg_scale);
    // load offset on the stack from the slot for this parameter
    ld(tmp2, Address(tmp2, 0));
    neg(tmp2, tmp2);

    // read the parameter from the local area
    shadd(tmp2, tmp2, xlocals, tmp2, Interpreter::logStackElementSize);
    ld(tmp2, Address(tmp2, 0));

    // profile the parameter
    shadd(t1, tmp1, t1, t0, per_arg_scale);
    Address arg_type(t1, 0);
    profile_obj_type(tmp2, arg_type, tmp3);

    // go to next parameter
    add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count());
    bgez(tmp1, loop);

    bind(profile_continue);
  }
}

void InterpreterMacroAssembler::get_method_counters(Register method,
                                                    Register mcs, Label& skip) {
  Label has_counters;
  ld(mcs, Address(method, Method::method_counters_offset()));
  bnez(mcs, has_counters);
  call_VM(noreg, CAST_FROM_FN_PTR(address,
          InterpreterRuntime::build_method_counters), method);
  ld(mcs, Address(method, Method::method_counters_offset()));
  beqz(mcs, skip); // No MethodCounters allocated, OutOfMemory
  bind(has_counters);
}

#ifdef ASSERT
void InterpreterMacroAssembler::verify_access_flags(Register access_flags, uint32_t flag_bits,
                                                    const char* msg, bool stop_by_hit) {
  Label L;
  andi(t0, access_flags, flag_bits);
  if (stop_by_hit) {
    beqz(t0, L);
  } else {
    bnez(t0, L);
  }
  stop(msg);
  bind(L);
}

void InterpreterMacroAssembler::verify_frame_setup() {
  Label L;
  const Address monitor_block_top(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
  ld(t0, monitor_block_top);
  beq(esp, t0, L);
  stop("broken stack frame setup in interpreter");
  bind(L);
}
#endif

Messung V0.5 in Prozent
C=87 H=94 G=90

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet am  2026-10-11) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.