Ejemplo n.º 1
0
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
                                            bool for_compiler_entry) {
  assert(method == rmethod, "interpreter calling convention");
  Label L_no_such_method;
  __ cbz(rmethod, L_no_such_method);
  __ verify_method_ptr(method);

  if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
    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.

    __ ldrb(rscratch1, Address(rthread, JavaThread::interp_only_mode_offset()));
    __ cbnz(rscratch1, run_compiled_code);
    __ ldr(rscratch1, Address(method, Method::interpreter_entry_offset()));
    __ br(rscratch1);
    __ BIND(run_compiled_code);
  }

  const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
                                                     Method::from_interpreted_offset();
  __ ldr(rscratch1,Address(method, entry_offset));
  __ br(rscratch1);
  __ bind(L_no_such_method);
  __ far_jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
}
Ejemplo n.º 2
0
void MacroAssembler::lowLevelDebug(const char *s,
								   Register ra,
								   Register rb,
								   Register rc)
{
	Q_ASSERT(ra.code() < 13 && rb.code() < 13 && rc.code() < 13);
	int preserved = 0x1fff | lr.bit();
	stm(db_w, sp, preserved);
	add(fp, sp, Operand(12*4));
	mrs(r4, CPSR);

	Label omitString;
	b(&omitString);

	int sPtr = intptr_t(buffer_ + pcOffset());
	do {
		db(*s);
	} while (*(s++));
	while (pcOffset() & 3)
		db('\0');

	bind(&omitString);
	ldr(r3, MemOperand(sp, rc.code()*4));
	ldr(r2, MemOperand(sp, rb.code()*4));
	ldr(r1, MemOperand(sp, ra.code()*4));
	mov(r0, Operand(sPtr));

	void (*qDebugPtr)(const char *,...) = &qDebug;
	mov(ip, Operand(intptr_t(qDebugPtr)));
	blx(ip);

	msr(CPSR_f, Operand(r4));
	ldm(ia_w, sp, preserved);
}
Ejemplo n.º 3
0
void ldr(int i)  /* left-down-right */
{
    if (i == 0) return;
    dlu(i - 1);  draw_rel(-h,  0);
    ldr(i - 1);  draw_rel( 0, -h);
    ldr(i - 1);  draw_rel( h,  0);
    urd(i - 1);
}
Ejemplo n.º 4
0
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
  const int code_length = VtableStub::pd_code_size_limit(true);
  VtableStub* s = new(code_length) VtableStub(true, vtable_index);
  // Can be NULL if there is no free space in the code cache.
  if (s == NULL) {
    return NULL;
  }

  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

  assert(VtableStub::receiver_location() == R0->as_VMReg(), "receiver expected in R0");

  const Register tmp = Rtemp; // Rtemp OK, should be free at call sites

  address npe_addr = __ pc();
  __ load_klass(tmp, R0);

  {
  int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes();
  int method_offset = vtableEntry::method_offset_in_bytes() + entry_offset;

  assert ((method_offset & (wordSize - 1)) == 0, "offset should be aligned");
  int offset_mask = AARCH64_ONLY(0xfff << LogBytesPerWord) NOT_AARCH64(0xfff);
  if (method_offset & ~offset_mask) {
    __ add(tmp, tmp, method_offset & ~offset_mask);
  }
  __ ldr(Rmethod, Address(tmp, method_offset & offset_mask));
  }

  address ame_addr = __ pc();
#ifdef AARCH64
  __ ldr(tmp, Address(Rmethod, Method::from_compiled_offset()));
  __ br(tmp);
#else
  __ ldr(PC, Address(Rmethod, Method::from_compiled_offset()));
#endif // AARCH64

  masm->flush();

  if (PrintMiscellaneous && (WizardMode || Verbose)) {
    tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
                  vtable_index, p2i(s->entry_point()),
                  (int)(s->code_end() - s->entry_point()),
                  (int)(s->code_end() - __ pc()));
  }
  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
  // FIXME ARM: need correct 'slop' - below is x86 code
  // shut the door on sizing bugs
  //int slop = 8;  // 32-bit offset is this much larger than a 13-bit one
  //assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}
Ejemplo n.º 5
0
void MethodHandles::verify_klass(MacroAssembler* _masm,
                                 Register obj, SystemDictionary::WKID klass_id,
                                 const char* error_message) {
  InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
  KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
  Register temp = rscratch2;
  Register temp2 = rscratch1; // used by MacroAssembler::cmpptr
  Label L_ok, L_bad;
  BLOCK_COMMENT("verify_klass {");
  __ verify_oop(obj);
  __ cbz(obj, L_bad);
  __ push(RegSet::of(temp, temp2), sp);
  __ load_klass(temp, obj);
  __ cmpptr(temp, ExternalAddress((address) klass_addr));
  __ br(Assembler::EQ, L_ok);
  intptr_t super_check_offset = klass->super_check_offset();
  __ ldr(temp, Address(temp, super_check_offset));
  __ cmpptr(temp, ExternalAddress((address) klass_addr));
  __ br(Assembler::EQ, L_ok);
  __ pop(RegSet::of(temp, temp2), sp);
  __ bind(L_bad);
  __ stop(error_message);
  __ BIND(L_ok);
  __ pop(RegSet::of(temp, temp2), sp);
  BLOCK_COMMENT("} verify_klass");
}
Ejemplo n.º 6
0
HANDLE StartPatcherThread( unsigned PID, DWORD *pPatcherThreadID = NULL)
{
	EnableDebugPrivilege();
	if (GetRemoteModuleHandle64Aware(PID, _T("VBoxDD.dll")))
	{
		//We are inside VirtualBox

#ifdef _WIN64
		if (GetRemoteModuleHandle64Aware(PID, _T("kdclient64.dll")))
#else
		if (GetRemoteModuleHandle64Aware(PID, _T("kdclient.dll")))
#endif
			return 0;


		if (!s_bUserWarnedAboutVBox)
		{
			s_bUserWarnedAboutVBox = true;
			MessageBox(0, _T("VirtualKD cannot patch VirtualBox on-the-fly.\r\nPlease register the VirtualKD device for VirtualBox by running \"regsvr32 VBoxKD64.dll\". If this does not help, close all instances of VirtualBox and terminate VBoxSVC.exe and try again."),
				_T("VirtualKD"),
				MB_ICONWARNING | MB_TASKMODAL);
		}
		return INVALID_HANDLE_VALUE;
	}
	RemoteDllLoader ldr(g_hThisDll, false);
	if (ldr.FindLibraryInProcess(PID))
		return NULL;
	return ldr.InitiateDLLLoading(PID, pPatcherThreadID);
}
Ejemplo n.º 7
0
/*!
	Adds cycles from cpuRecData.additionalCycles to mCycles and sets
	cpuRecData.additionalCycles to 0. additionalCycles member holds
	postponed cycles in case of interrupt pending or DMA transfer.
 */
void NesCpuTranslator::mFetchAdditionalCycles()
{
	__ ldr(ip, MemOperand(mDataBase, offsetof(NesCpuRecData,additionalCycles)));
	__ add(mCycles, mCycles, Operand(ip), SetCC);
	__ mov(ip, Operand(0));
	__ str(ip, MemOperand(mDataBase, offsetof(NesCpuRecData,additionalCycles)));
}
Ejemplo n.º 8
0
void urd(int i)  /* up-right-down */
{
    if (i == 0) return;
    rul(i - 1);  draw_rel( 0,  h);
    urd(i - 1);  draw_rel( h,  0);
    urd(i - 1);  draw_rel( 0, -h);
    ldr(i - 1);
}
Ejemplo n.º 9
0
void dlu(int i)  /* down-left-up */
{
    if (i == 0) return;
    ldr(i - 1);  draw_rel( 0, -h);
    dlu(i - 1);  draw_rel(-h,  0);
    dlu(i - 1);  draw_rel( 0,  h);
    rul(i - 1);
}
Ejemplo n.º 10
0
void aplicar_ldr(configuracion_t *config)
{
	ldr_fn_t *ldr = SWITCH_C_ASM ( config, ldr_c, ldr_asm ) ;
	buffer_info_t info = config->src;
	ldr(info.bytes, config->dst.bytes, info.width, info.height, info.width_with_padding,
	         config->dst.width_with_padding, alpha);

}
Ejemplo n.º 11
0
void NesCpuTranslator::mRestoreInternalFlags()
{
#if !defined(FRAME_POINTER_FOR_GDB)
	__ msr(CPSR_f, Operand(mInternalFlagsCopy));
#else
	__ ldr(ip, MemOperand(mDataBase, offsetof(NesCpuRecData,internalFlagsCopy)));
	__ msr(CPSR_f, Operand(ip));
#endif
}
Ejemplo n.º 12
0
void NesSyncCompiler::mCallCFunction(int offsetInData)
{
#if defined(CAN_USE_ARMV7_INSTRUCTIONS)
	__ mov(ip, Operand(*(u32 *)((u8 *)&syncData + offsetInData)));
	__ blx(ip);
#else
	__ ldr(ip, MemOperand(m_dataBase, offsetInData));
	__ blx(ip);
#endif
}
Ejemplo n.º 13
0
HANDLE StartUnpatcherThread( unsigned PID, DWORD *pPatcherThreadID = NULL)
{
	if (GetRemoteModuleHandle64Aware(PID, _T("VBoxDD0.dll")))
		return INVALID_HANDLE_VALUE;
	EnableDebugPrivilege();
	RemoteDllLoader ldr(g_hThisDll, false);
	if (!ldr.FindLibraryInProcess(PID))
		return NULL;
	return ldr.InitiateDLLUnloading(PID, true, pPatcherThreadID);
}
Ejemplo n.º 14
0
/*!
	Compiles a code that loads address pointed by a label at the given \a offset
	in 6502 address space to the \a dst. The label can be bound to the
	recompiled code or to mTranslateCaller if translation haven't occured for
	the given \a offset.
 */
inline void NesCpuTranslator::mLoadLabelAddress(Register offset, Register dst)
{
	Q_ASSERT(offset != ip && dst != ip);

	__ mov(dst, Operand(intptr_t(m_codeBuffer)));
	__ mov(ip, Operand(intptr_t(m_labels)));
	__ ldr(ip, MemOperand(ip, offset, LSL, 2));
	// dst = buffer - pos - 1
	__ sub(dst, dst, Operand(ip));
	__ bic(dst, dst, Operand(3));
}
Ejemplo n.º 15
0
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
                                        Register recv, Register method_temp,
                                        Register temp2,
                                        bool for_compiler_entry) {
  BLOCK_COMMENT("jump_to_lambda_form {");
  // This is the initial entry point of a lazy method handle.
  // After type checking, it picks up the invoker from the LambdaForm.
  assert_different_registers(recv, method_temp, temp2);
  assert(recv != noreg, "required register");
  assert(method_temp == rmethod, "required register for loading method");

  //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });

  // Load the invoker, as MH -> MH.form -> LF.vmentry
  __ verify_oop(recv);
  __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
  __ verify_oop(method_temp);
  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
  __ verify_oop(method_temp);
  // the following assumes that a Method* is normally compressed in the vmtarget field:
  __ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));

  if (VerifyMethodHandles && !for_compiler_entry) {
    // make sure recv is already on stack
    __ ldr(temp2, Address(method_temp, Method::const_offset()));
    __ load_sized_value(temp2,
                        Address(temp2, ConstMethod::size_of_parameters_offset()),
                        sizeof(u2), /*is_signed*/ false);
    // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
    Label L;
    __ ldr(rscratch1, __ argument_address(temp2, -1));
    __ cmp(recv, rscratch1);
    __ br(Assembler::EQ, L);
    __ ldr(r0, __ argument_address(temp2, -1));
    __ hlt(0);
    __ BIND(L);
  }

  jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
  BLOCK_COMMENT("} jump_to_lambda_form");
}
Ejemplo n.º 16
0
JSPluginsLoader::JSPluginsLoader(const QScriptProgram &plugin) throw(JSError){
    if(loader.isEmpty()){
        QFile ldr(":/jshelper/jspluginsloader.js");
        ldr.open(QIODevice::ReadOnly);
        loader = ldr.readAll();
    }
    eng.evaluate(loader);
    eng.evaluate(plugin);
    if(eng.hasUncaughtException()){
        throw JSError(eng.uncaughtExceptionLineNumber(), eng.uncaughtException().toString());
    }
}
Ejemplo n.º 17
0
bool PluginLoader::loadPlugin(QString lib)
{
    QPluginLoader ldr(lib);
    QObject *obj= ldr.instance();
    PluginInterface *ifc=qobject_cast<PluginInterface *>(obj);
    if(!ldr.isLoaded()){
      qDebug()<<"Plugin" << lib << "not loaded:"<< ldr.errorString();
      return false;
    }
    plugins->append(ifc);
    return true;
}
Ejemplo n.º 18
0
bool CPersistKitList::Load()
{
  wxString sFile;
  CILSLadderInfo ldr(true);
  CIncrementer x(m_nInLoad);
  if(!ldr.IsOK())
  {
    _SetLoadError();
  }
  vector<CILSkit *> *pvKits = ldr.GetKits();
  vector<CILSkit *>::iterator itr;
  CILSkit *pKit;
  int nCount = 0;
  m_bV1 = false;
  Clear();

  // load all kit xml files

  for(itr = pvKits->begin();
      itr != pvKits->end();
      ++itr)
  {
    pKit = *itr;
    m_sLastKit = pKit->GetKitName();
    m_pLastKitLocus = NULL;
    m_pLastKitLS = NULL;
    LSitr itrLS = m_mLS.find(m_sLastKit);
    m_pLastKitLS = 
      (itrLS == m_mLS.end())
      ? NULL
      : itrLS->second;
    KLNCitr itrLocus = m_mapKitLocus.find(m_sLastKit);
    m_pLastKitLocus =
      (itrLocus == m_mapKitLocus.end())
      ? NULL
      : itrLocus->second;

    sFile = pKit->GetFilePath();
    if(LoadFile(sFile))
    {
      Add(m_sLastKit);
      nCount++;
    }
    else
    {
      _AddError();
    }
  }
  nwxString::Trim(&m_sErrorMsg);
  SortILS();
  return (nCount > 0);
}
Ejemplo n.º 19
0
bool IsVMSessionPatched( unsigned PID )
{
#ifndef _WIN64
	if (IsRundll64Required(PID))
	{
		return (Call64BitKDCLIENT(kIsSessionPatched, PID) == 1);
	}
#endif
	if (GetRemoteModuleHandle64Aware(PID, _T("VBoxDD0.dll")))
		return true;
	RemoteDllLoader ldr(g_hThisDll, false);
	return (ldr.FindLibraryInProcess(PID, true) != 0);
}
Ejemplo n.º 20
0
inline void NesCpuTranslator::mCheckAlert()
{
	// check if write caused an alert
	__ ldr(ip, MemOperand(mDataBase, offsetof(NesCpuRecData,alert)));
	__ add(pc, pc, Operand(ip, LSL, 2));
	// some pad needed - write current 6502.PC
	__ dd(currentPc());
	// save state can happen in alert handler - r0 must contain 6502.PC
	__ mov(r0, Operand(currentPc()));
	// handle an alert if needed
	__ bl(&m_alertHandlerLabel);
	// continue otherwise
}
Ejemplo n.º 21
0
void NesCpuTranslator::mHandleInterrupts()
{
	// code at the bottom does following job:
	//
	// if (interrupts & mNmiInterrupt) {
	//     hwInterrupt(NmiVectorAddress);
	//     interrupts &= ~mNmiInterrupt;
	// } else if (interrupts & mIrqInterrupt) {
	//     if (!(mFlags & mIrqDisable)) {
	//         hwInterrupt(IrqVectorAddress);
	//     }
	// }

	// r0 - 6502.PC address of the next instruction

	Label exitInterruptCheck;
	Label irqPending;
	Label doInterrupt;

	__ ldr(r1, MemOperand(mDataBase, offsetof(NesCpuRecData,interrupts)));
	__ mov(r1, r1, SetCC);
	__ b(&exitInterruptCheck, eq);

	__ tst(r1, Operand(NesCpuBase::NmiInterrupt));
	__ b(&irqPending, eq);

	// NMI is handled here
	// clear NMI flag
	__ bic(r1, r1, Operand(NesCpuBase::NmiInterrupt));
	__ str(r1, MemOperand(mDataBase, offsetof(NesCpuRecData,interrupts)));
	__ mov(r1, Operand(NesCpuBase::NmiVectorAddress));
	__ b(&doInterrupt);

// irqPending:
	// IRQ is handled here
	// check if P.I is cleared
	__ bind(&irqPending);
	__ tst(mFlags, Operand(NesCpuBase::IrqDisable));
	__ b(&exitInterruptCheck, ne);
	__ mov(r1, Operand(NesCpuBase::IrqVectorAddress));

// doInterrupt:
	__ bind(&doInterrupt);
	// interrupt occured - handle it
	mHwInterrupt();

// exitInterruptCheck:
	__ bind(&exitInterruptCheck);
}
Ejemplo n.º 22
0
		HMODULE __stdcall FindLoadedModuleHandle(LPCWSTR name)
		{
			assert(name != NULL);
			LdrDataTable ldr(LdrDataTableModuleList::InLoadOrderModuleList);
			auto result = _STD find_if(ldr.begin(), ldr.end(), [name](LDR_DATA_TABLE_ENTRY_Ex& val)
			{
				auto moduleName = val.BaseDllName.Buffer;
				return moduleName != nullptr && _wcsicmp(name, moduleName) == 0;
			});
			if (result == ldr.end())
			{
				return nullptr;
			}
			return (HMODULE)result->DllBase;
		}
Ejemplo n.º 23
0
void InterpreterStubs::generate_current_thread_to_primordial() {
  Segment seg(this, code_segment, "Current thread to primordial");
  bind_global("current_thread_to_primordial");
  
  comment("Set up global pointer, as we can be called from C code");
  ldr_gp_base(gp);
  
  bind_global("current_thread_to_primordial_fast");

  // We're never going to return to this thread, so it doesn't matter if
  // it doesn't look like a stopped Java thread anymore.
  get_primordial_sp(sp);
  comment("restore permanent registers (including return address)");
  ldr(lr, imm_index(sp, BytesPerWord, post_indexed));
  ldmfd(sp, range(r3, r11), writeback);
  jmpx(lr);

  if (GenerateDebugAssembly) {
    bind_local("interpreter_bkpt");
    get_gp_bytecode_counter(tmp3);
    add(tmp3, tmp3, imm(1));
    set_gp_bytecode_counter(tmp3);
    mov(pc, reg(tmp0));
  }

#if ENABLE_XSCALE_WMMX_TIMER_TICK && !ENABLE_TIMER_THREAD
  // set timer_tick from WMMX wCASF register
  comment("wmmx_set_timer_tick to set timer_tick from WMMX register");
  bind_global("wmmx_set_timer_tick");
  // tmrc(r2, wCASF);
  define_long(0xEE132110);
  mvn(r3, imm(4) );
  andr(r2, r2, reg(r3) );
  // tmcr(wCASF, r2);
  define_long(0xEE032110);
  jmpx(lr);
  // clear timer_tick from WMMX wCASF register
  comment("wmmx_set_timer_tick to clear timer_tick from WMMX register");
  bind_global("wmmx_clear_timer_tick");
  define_long(0xEE100060); 
//  wcmpgtub(wR0, wR0, wR0);
  jmpx(lr);
#endif // ENABLE_XSCALE_WMMX_TIMER_TICK && !ENABLE_TIMER_THREAD

}
Ejemplo n.º 24
0
void NesSyncCompiler::mEntryPoint()
{
	// r0 = additionalCpuCycles - the amount of cycles that CPU emulation
	//      executed minus requested cycles to execute

	__ stm(db_w, sp, m_regList | lr.bit());
#if defined(FRAME_POINTER_FOR_GDB)
	__ add(fp, sp, Operand(3*4)); // point to lr - omit r9,r10,fp
#endif
	// one step before we passed an amount of cycles that CPU should run,
	// but it's almost impossible to clock CPU by exact cycles, it will
	// often run more, and we must track these additional cycles
	// save additional CPU cycles, they will be used later in mClock
	__ mov(m_additionalCpuCycles, r0);
	// jump to the point the frame generation was before
	__ mov(m_dataBase, Operand(reinterpret_cast<int>(&syncData)));
	__ ldr(pc, MemOperand(m_dataBase, offsetof(NesSyncData,nextPc)));
}
Ejemplo n.º 25
0
HANDLE StartPatcherThread( unsigned PID, DWORD *pPatcherThreadID = NULL)
{
	EnableDebugPrivilege();
	if (GetRemoteModuleHandle64Aware(PID, _T("VBoxDD0.dll")))
		return 0;
	if (GetRemoteModuleHandle64Aware(PID, _T("VBoxDD.dll")))
	{
		if (!s_bUserWarnedAboutVBox)
		{
			s_bUserWarnedAboutVBox = true;
			MessageBox(0, _T("VirtualKD cannot patch VirtualBox on-the-fly.\r\nPlease, shut down all your VMs, rename VBoxDD.dll\t\nto VBoxDD0.dll and copy VBoxDD.dll from VirtualKD\t\npackage to VirtualBox directory."),
				_T("VirtualKD"),
				MB_ICONWARNING | MB_TASKMODAL);
		}
		return INVALID_HANDLE_VALUE;
	}
	RemoteDllLoader ldr(g_hThisDll, false);
	if (ldr.FindLibraryInProcess(PID))
		return NULL;
	return ldr.InitiateDLLLoading(PID, pPatcherThreadID);
}
Ejemplo n.º 26
0
void Integrator::writeBuffers(const std::string &suffix, bool overwrite)
{
    Vec2u res = _scene->cam().resolution();
    std::unique_ptr<Vec3f[]> hdr(new Vec3f[res.product()]);
    std::unique_ptr<Vec3c[]> ldr(new Vec3c[res.product()]);

    for (uint32 y = 0; y < res.y(); ++y)
        for (uint32 x = 0; x < res.x(); ++x)
            hdr[x + y*res.x()] = _scene->cam().getLinear(x, y);

    for (uint32 i = 0; i < res.product(); ++i)
        ldr[i] = Vec3c(clamp(Vec3i(_scene->cam().tonemap(hdr[i])*255.0f), Vec3i(0), Vec3i(255)));

    const RendererSettings &settings = _scene->rendererSettings();

    if (!settings.outputFile().empty())
        ImageIO::saveLdr(incrementalFilename(settings.outputFile(), suffix, overwrite),
                &ldr[0].x(), res.x(), res.y(), 3);
    if (!settings.hdrOutputFile().empty())
        ImageIO::saveHdr(incrementalFilename(settings.hdrOutputFile(), suffix, overwrite),
                &hdr[0].x(), res.x(), res.y(), 3);
}
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
  const char *name;
  switch (type) {
    case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    case T_BYTE:    name = "jni_fast_GetByteField";    break;
    case T_CHAR:    name = "jni_fast_GetCharField";    break;
    case T_SHORT:   name = "jni_fast_GetShortField";   break;
    case T_INT:     name = "jni_fast_GetIntField";     break;
    case T_LONG:    name = "jni_fast_GetLongField";    break;
    case T_FLOAT:   name = "jni_fast_GetFloatField";   break;
    case T_DOUBLE:  name = "jni_fast_GetDoubleField";  break;
    default:        ShouldNotReachHere();
  }
  ResourceMark rm;
  BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
  CodeBuffer cbuf(blob);
  MacroAssembler* masm = new MacroAssembler(&cbuf);
  address fast_entry = __ pc();

  Label slow;

  unsigned long offset;
  __ adrp(rcounter_addr,
	  SafepointSynchronize::safepoint_counter_addr(), offset);
  Address safepoint_counter_addr(rcounter_addr, offset);
  __ ldrw(rcounter, safepoint_counter_addr);
  __ andw(rscratch1, rcounter, 1);
  __ cbnzw(rscratch1, slow);
  __ eor(robj, c_rarg1, rcounter);
  __ eor(robj, robj, rcounter);               // obj, since
                                              // robj ^ rcounter ^ rcounter == robj
                                              // robj is address dependent on rcounter.
  __ ldr(robj, Address(robj, 0));             // *obj
  __ lsr(roffset, c_rarg2, 2);                // offset

  assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  speculative_load_pclist[count] = __ pc();   // Used by the segfault handler
  switch (type) {
    case T_BOOLEAN: __ ldrb    (result, Address(robj, roffset)); break;
    case T_BYTE:    __ ldrsb   (result, Address(robj, roffset)); break;
    case T_CHAR:    __ ldrh    (result, Address(robj, roffset)); break;
    case T_SHORT:   __ ldrsh   (result, Address(robj, roffset)); break;
    case T_FLOAT:   __ ldrw    (result, Address(robj, roffset)); break;
    case T_INT:     __ ldrsw   (result, Address(robj, roffset)); break;
    case T_DOUBLE:
    case T_LONG:    __ ldr     (result, Address(robj, roffset)); break;
    default:        ShouldNotReachHere();
  }

  // counter_addr is address dependent on result.
  __ eor(rcounter_addr, rcounter_addr, result);
  __ eor(rcounter_addr, rcounter_addr, result);
  __ ldrw(rscratch1, safepoint_counter_addr);
  __ cmpw(rcounter, rscratch1);
  __ br (Assembler::NE, slow);

  switch (type) {
    case T_FLOAT:   __ fmovs(v0, result); break;
    case T_DOUBLE:  __ fmovd(v0, result); break;
    default:        __ mov(r0, result);   break;
  }
  __ ret(lr);

  slowcase_entry_pclist[count++] = __ pc();
  __ bind(slow);
  address slow_case_addr;
  switch (type) {
    case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
    case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
    case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
    case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
    case T_LONG:    slow_case_addr = jni_GetLongField_addr();    break;
    case T_FLOAT:   slow_case_addr = jni_GetFloatField_addr();   break;
    case T_DOUBLE:  slow_case_addr = jni_GetDoubleField_addr();  break;
    default:        ShouldNotReachHere();
  }

  {
    __ enter();
    __ lea(rscratch1, ExternalAddress(slow_case_addr));
    __ blr(rscratch1);
    __ maybe_isb();
    __ leave();
    __ ret(lr);
  }
  __ flush ();

  return fast_entry;
}
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
  address entry = __ pc();

  __ andr(esp, esp, -16);
  __ mov(c_rarg3, esp);
  // rmethod
  // rlocals
  // c_rarg3: first stack arg - wordSize

  // adjust sp
  __ sub(sp, c_rarg3, 18 * wordSize);
  __ str(lr, Address(__ pre(sp, -2 * wordSize)));
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address,
                              InterpreterRuntime::slow_signature_handler),
             rmethod, rlocals, c_rarg3);

  // r0: result handler

  // Stack layout:
  // rsp: return address           <- sp
  //      1 garbage
  //      8 integer args (if static first is unused)
  //      1 float/double identifiers
  //      8 double args
  //        stack args              <- esp
  //        garbage
  //        expression stack bottom
  //        bcp (NULL)
  //        ...

  // Restore LR
  __ ldr(lr, Address(__ post(sp, 2 * wordSize)));

  // Do FP first so we can use c_rarg3 as temp
  __ ldrw(c_rarg3, Address(sp, 9 * wordSize)); // float/double identifiers

  for (int i = 0; i < Argument::n_float_register_parameters_c; i++) {
    const FloatRegister r = as_FloatRegister(i);

    Label d, done;

    __ tbnz(c_rarg3, i, d);
    __ ldrs(r, Address(sp, (10 + i) * wordSize));
    __ b(done);
    __ bind(d);
    __ ldrd(r, Address(sp, (10 + i) * wordSize));
    __ bind(done);
  }

  // c_rarg0 contains the result from the call of
  // InterpreterRuntime::slow_signature_handler so we don't touch it
  // here.  It will be loaded with the JNIEnv* later.
  __ ldr(c_rarg1, Address(sp, 1 * wordSize));
  for (int i = c_rarg2->encoding(); i <= c_rarg7->encoding(); i += 2) {
    Register rm = as_Register(i), rn = as_Register(i+1);
    __ ldp(rm, rn, Address(sp, i * wordSize));
  }

  __ add(sp, sp, 18 * wordSize);
  __ ret(lr);

  return entry;
}
Ejemplo n.º 29
0
void InterpreterStubs::generate_interpreter_fill_in_tags() {
  Segment seg(this, code_segment, "Interpreter fill in tags");

  Register param_size = tmp0; // must be preserved
  Register callinfo   = tmp1;

  {
      bind_local("interpreter_fill_in_tags");
      comment("%s: size of parameters",       reg_name(tmp0));
      comment("%s: call info from call size", reg_name(tmp1));
      comment("");
      comment("Must preserve lr, %s (method), and %s (parameter size)", 
              reg_name(r0), reg_name(tmp0));

      Label loop_entry;

      // tos_val = r0 must be preserved
      Register arg_index  = tmp2;
      Register one_reg    = tmp3;
      Register tag_address = JavaStackDirection < 0 ? tmp4 : jsp;

      mov_imm(one_reg, 1 << CallInfo::format1_tag_start);
      sub(arg_index, param_size, one, set_CC);
      report_fatal("shouldn't be called on no arguments", lt);

      if (JavaStackDirection < 0) { 
        comment("Tag address of last argument");
        add(tag_address, jsp, imm(BytesPerWord));
      } else { 
        comment("jsp points to tag address of last argument");
      }

    bind(loop_entry);
      comment("test the bit in the call info");
      tst(callinfo, reg_shift(one_reg, lsl, arg_index));

      mov(tos_tag, imm(obj_tag), ne);
      mov(tos_tag, imm(int_tag), eq);
      if (JavaStackDirection < 0) { 
        str(tos_tag, add_index(tag_address, arg_index, lsl, 3));
      } else {
        str(tos_tag, sub_index(tag_address, arg_index, lsl, 3));
      }
      sub(arg_index, arg_index, one, set_CC);
      b(loop_entry, ge);
      mov(pc, reg(locals));
  }
  {
    Register bit_offset  = tmp1; // callinfo not needed
    Register one_reg     = tmp2;
    Register tag_address = tmp3;
    Register x1          = tmp4;
    Register x2          = tmp5;
    Register index       = tos_tag;
    Label loop;

    bind_local("interpreter_fill_in_extended_tags");
       comment("Total number of tags");
       if (HARDWARE_LITTLE_ENDIAN) {
         ldrh(bit_offset, imm_index3(lr, -2 * BytesPerWord));
       } else {
         ldrh(bit_offset, imm_index3(lr, -2 * BytesPerWord + 2));
       }

       comment("Tag address of first argument");
       if (JavaStackDirection < 0) {
         add(tag_address, jsp, imm_shift(param_size, lsl, 3));
       } else { 
         sub(tag_address, jsp, imm_shift(param_size, lsl, 3));
       }
       // tag_address points to the last address of the previous stack
       add_imm(tag_address, tag_address,
               JavaFrame::arg_offset_from_sp(-1) + BytesPerWord);

       comment("Index of last argument");
       sub(index, param_size, one);    

       comment("Bit number of first argument");
       sub(bit_offset, bit_offset, reg(param_size));
       mov(bit_offset, imm_shift(bit_offset, lsl, 2));
       add(bit_offset, bit_offset, imm(32 + 32 + 16));

       comment("A useful constant");
       mov(one_reg, one);

    bind(loop);
       comment("Get the bit offset for this argument");
       add(x1, bit_offset, imm_shift(index, lsl, 2));

       comment("Get the appropriate word");
       mov(x2, imm_shift(x1, lsr, 5));
       ldr(x2, sub_index(lr, x2, lsl, 2));

       comment("Pick out the nybble");
       andr(x1, x1, imm(31));
       mov(x2, reg_shift(x2, lsr, x1));
       andr(x2, x2, imm(15), set_CC);

       comment("Convert the nybble into a stack type");
       sub(x2, x2, one,                     ne);
       mov(x2, reg_shift(one_reg, lsl, x2), ne);
       if (JavaStackDirection < 0) {
         str(x2, sub_index(tag_address, index, lsl, 3));
       } else {
         str(x2, add_index(tag_address, index, lsl, 3));
       }
       comment("Update the info");
       sub(index, index, one, set_CC);
       b(loop, ge);
       mov(pc, reg(locals));
  }
}
Ejemplo n.º 30
0
void InterpreterStubs::generate_primordial_to_current_thread() {
  Segment seg(this, code_segment, "Primordial to current thread");

bind_global("primordial_to_current_thread");
  comment("save permanent registers (including return address)");
  stmfd(sp, range(r3, r11), writeback);
  str(lr, imm_index(sp, -BytesPerWord, pre_indexed));

  comment("Set up global pointer");
  ldr_gp_base(gp);

  comment("Get current thread");
  get_thread(r1);

  comment("Save primordial stack pointer");
  set_primordial_sp(sp);

  comment("Get new stack pointer");
  ldr(jsp, imm_index(r1, Thread::stack_pointer_offset()));
  
  comment("Go to code");
  ldr(lr, imm_index(jsp, -JavaStackDirection * BytesPerWord));
  ldr(fp, imm_index(jsp, -JavaStackDirection * 2 * BytesPerWord, post_indexed));
  jmpx(lr);

bind_global("start_lightweight_thread_asm");
  Label testing_compiler; 
  const int SignedBytesPerWord = JavaStackDirection * BytesPerWord;

  comment("Set up global pointer");
  ldr_gp_base(gp);
  // jsp       => Thread::lightweight_thread_exit
  // jsp +- 4   => Thread::lightweight_thread_uncaught_exception
  // jsp +- 8   => Thread::finish
  // jsp +- 12  => force_terminated
  // jsp +- 16  => TestCompiler

  comment("Invoke pending entries unless the thread is being terminated");
  get_thread(r0);
  comment("r1 = THREAD->status();");
  ldr(r1, imm_index(r0, Thread::status_offset()));
  mov(r2, zero);
  comment("if ((r1 & THREAD_TERMINATING) != 0) {");
  tst(r1, imm(THREAD_TERMINATING));
  comment("  THREAD->pending_entries = NULL;");
  str(r2, imm_index(r0, Thread::pending_entries_offset()), ne);
  comment("} else {");
  comment("  invoke_pending_entries(THREAD)");
  bl("invoke_pending_entries", eq);
  comment("}");

  comment("if (!TestCompiler) {");
  ldr(r0, imm_index(jsp, -4 * SignedBytesPerWord));
  get_current_pending_exception(r1);
  cmp(r0, zero);
  b(testing_compiler, ne);

  comment("  if (Thread::current_has_pending_exception()) {");
  comment("    call_on_primordial_stack(lightweight_thread_uncaught_exception);");
  comment("  }");
  cmp(r1, zero);
  ldr(r0, imm_index(jsp, -1 * SignedBytesPerWord), ne);
  bl("call_on_primordial_stack",                   ne); 

  comment("  call_on_primordial_stack(finish);");
  ldr(r0, imm_index(jsp, -2 * SignedBytesPerWord));
  bl("call_on_primordial_stack");   

  comment("  invoke_pending_entries(THREAD);");
  get_thread(r0);
  bl("invoke_pending_entries");

  comment("  force_terminated()");
  ldr(r0, imm_index(jsp, -3 * SignedBytesPerWord));  
  bl("call_on_primordial_stack");
  comment("}");  
#if ENABLE_ISOLATES
  comment("Terminate the task if no other threads on it");
  ldr_label(r0, "thread_task_cleanup");
  bl("call_on_primordial_stack");   
  comment("  invoke_pending_entries(THREAD);");
  get_thread(r0);
  bl("invoke_pending_entries");
#endif

bind_global(testing_compiler);
  comment("call_on_primordial_stack(lightweight_thread_exit);");
  ldr(r0, imm_index(jsp));
  bl("call_on_primordial_stack");

  comment("GUARANTEE(Scheduler::_next_runnable_thread == NULL");

  ldr_label(r0, "_next_runnable_thread");
  ldr(r0, imm_index(r0));
  cmp(r0, zero);
  breakpoint(ne);

  comment("current_thread_to_primordial();");
  bl("current_thread_to_primordial_fast");
  breakpoint();
}