⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macro-assembler-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
  fcompp();  push(eax);  fnstsw_ax();  sahf();  pop(eax);}void MacroAssembler::EnterInternalFrame() {  int type = StackFrame::INTERNAL;  push(ebp);  mov(ebp, Operand(esp));  push(esi);  push(Immediate(Smi::FromInt(type)));  push(Immediate(0));  // Push an empty code cache slot.}void MacroAssembler::LeaveInternalFrame() {  if (FLAG_debug_code) {    StackFrame::Type type = StackFrame::INTERNAL;    cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset),        Immediate(Smi::FromInt(type)));    Check(equal, "stack frame types must match");  }  leave();}void MacroAssembler::EnterExitFrame(StackFrame::Type type) {  ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);  // Setup the frame structure on the stack.  ASSERT(ExitFrameConstants::kPPDisplacement == +2 * kPointerSize);  ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);  ASSERT(ExitFrameConstants::kCallerFPOffset ==  0 * kPointerSize);  push(ebp);  mov(ebp, Operand(esp));  // Reserve room for entry stack pointer and push the debug marker.  ASSERT(ExitFrameConstants::kSPOffset  == -1 * kPointerSize);  push(Immediate(0));  // saved entry sp, patched before call  push(Immediate(type == StackFrame::EXIT_DEBUG ? 1 : 0));  // Save the frame pointer and the context in top.  ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);  ExternalReference context_address(Top::k_context_address);  mov(Operand::StaticVariable(c_entry_fp_address), ebp);  mov(Operand::StaticVariable(context_address), esi);  // Setup argc and argv in callee-saved registers.  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;  mov(edi, Operand(eax));  lea(esi, Operand(ebp, eax, times_4, offset));  // Save the state of all registers to the stack from the memory  // location. This is needed to allow nested break points.  if (type == StackFrame::EXIT_DEBUG) {    // TODO(1243899): This should be symmetric to    // CopyRegistersFromStackToMemory() but it isn't! esp is assumed    // correct here, but computed for the other call. Very error    // prone! FIX THIS.  Actually there are deeper problems with    // register saving than this asymmetry (see the bug report    // associated with this issue).    PushRegistersFromMemory(kJSCallerSaved);  }  // Reserve space for two arguments: argc and argv.  sub(Operand(esp), Immediate(2 * kPointerSize));  // Get the required frame alignment for the OS.  static const int kFrameAlignment = OS::ActivationFrameAlignment();  if (kFrameAlignment > 0) {    ASSERT(IsPowerOf2(kFrameAlignment));    and_(esp, -kFrameAlignment);  }  // Patch the saved entry sp.  mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp);}void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {  // Restore the memory copy of the registers by digging them out from  // the stack. This is needed to allow nested break points.  if (type == StackFrame::EXIT_DEBUG) {    // It's okay to clobber register ebx below because we don't need    // the function pointer after this.    const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;    int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;    lea(ebx, Operand(ebp, kOffset));    CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved);  }  // Get the return address from the stack and restore the frame pointer.  mov(ecx, Operand(ebp, 1 * kPointerSize));  mov(ebp, Operand(ebp, 0 * kPointerSize));  // Pop the arguments and the receiver from the caller stack.  lea(esp, Operand(esi, 1 * kPointerSize));  // Restore current context from top and clear it in debug mode.  ExternalReference context_address(Top::k_context_address);  mov(esi, Operand::StaticVariable(context_address));  if (kDebug) {    mov(Operand::StaticVariable(context_address), Immediate(0));  }  // Push the return address to get ready to return.  push(ecx);  // Clear the top frame.  ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);  mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0));}void MacroAssembler::PushTryHandler(CodeLocation try_location,                                    HandlerType type) {  ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize);  // adjust this code  // The pc (return address) is already on TOS.  if (try_location == IN_JAVASCRIPT) {    if (type == TRY_CATCH_HANDLER) {      push(Immediate(StackHandler::TRY_CATCH));    } else {      push(Immediate(StackHandler::TRY_FINALLY));    }    push(Immediate(Smi::FromInt(StackHandler::kCodeNotPresent)));    push(ebp);    push(edi);  } else {    ASSERT(try_location == IN_JS_ENTRY);    // The parameter pointer is meaningless here and ebp does not    // point to a JS frame. So we save NULL for both pp and ebp. We    // expect the code throwing an exception to check ebp before    // dereferencing it to restore the context.    push(Immediate(StackHandler::ENTRY));    push(Immediate(Smi::FromInt(StackHandler::kCodeNotPresent)));    push(Immediate(0));  // NULL frame pointer    push(Immediate(0));  // NULL parameter pointer  }  // Cached TOS.  mov(eax, Operand::StaticVariable(ExternalReference(Top::k_handler_address)));  // Link this handler.  mov(Operand::StaticVariable(ExternalReference(Top::k_handler_address)), esp);}Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg,                                   JSObject* holder, Register holder_reg,                                   Register scratch,                                   Label* miss) {  // Make sure there's no overlap between scratch and the other  // registers.  ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg));  // Keep track of the current object in register reg.  Register reg = object_reg;  int depth = 1;  // Check the maps in the prototype chain.  // Traverse the prototype chain from the object and do map checks.  while (object != holder) {    depth++;    // Only global objects and objects that do not require access    // checks are allowed in stubs.    ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded());    JSObject* prototype = JSObject::cast(object->GetPrototype());    if (Heap::InNewSpace(prototype)) {      // Get the map of the current object.      mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));      cmp(Operand(scratch), Immediate(Handle<Map>(object->map())));      // Branch on the result of the map check.      j(not_equal, miss, not_taken);      // Check access rights to the global object.  This has to happen      // after the map check so that we know that the object is      // actually a global object.      if (object->IsJSGlobalObject()) {        CheckAccessGlobal(reg, scratch, miss);        // Restore scratch register to be the map of the object.  We        // load the prototype from the map in the scratch register.        mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));      }      // The prototype is in new space; we cannot store a reference      // to it in the code. Load it from the map.      reg = holder_reg;  // from now the object is in holder_reg      mov(reg, FieldOperand(scratch, Map::kPrototypeOffset));    } else {      // Check the map of the current object.      cmp(FieldOperand(reg, HeapObject::kMapOffset),          Immediate(Handle<Map>(object->map())));      // Branch on the result of the map check.      j(not_equal, miss, not_taken);      // Check access rights to the global object.  This has to happen      // after the map check so that we know that the object is      // actually a global object.      if (object->IsJSGlobalObject()) {        CheckAccessGlobal(reg, scratch, miss);      }      // The prototype is in old space; load it directly.      reg = holder_reg;  // from now the object is in holder_reg      mov(reg, Handle<JSObject>(prototype));    }    // Go to the next object in the prototype chain.    object = prototype;  }  // Check the holder map.  cmp(FieldOperand(reg, HeapObject::kMapOffset),      Immediate(Handle<Map>(holder->map())));  j(not_equal, miss, not_taken);  // Log the check depth.  LOG(IntEvent("check-maps-depth", depth));  // Perform security check for access to the global object and return  // the holder register.  ASSERT(object == holder);  ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded());  if (object->IsJSGlobalObject()) {    CheckAccessGlobal(reg, scratch, miss);  }  return reg;}void MacroAssembler::CheckAccessGlobal(Register holder_reg,                                       Register scratch,                                       Label* miss) {  ASSERT(!holder_reg.is(scratch));  // Load the security context.  ExternalReference security_context =      ExternalReference(Top::k_security_context_address);  mov(scratch, Operand::StaticVariable(security_context));  // When generating debug code, make sure the security context is set.  if (FLAG_debug_code) {    cmp(Operand(scratch), Immediate(0));    Check(not_equal, "we should not have an empty security context");  }  // Load the global object of the security context.  int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;  mov(scratch, FieldOperand(scratch, offset));  // Check that the security token in the calling global object is  // compatible with the security token in the receiving global  // object.  mov(scratch, FieldOperand(scratch, JSGlobalObject::kSecurityTokenOffset));  cmp(scratch, FieldOperand(holder_reg, JSGlobalObject::kSecurityTokenOffset));  j(not_equal, miss, not_taken);}void MacroAssembler::NegativeZeroTest(Register result,                                      Register op,                                      Label* then_label) {  Label ok;  test(result, Operand(result));  j(not_zero, &ok, taken);  test(op, Operand(op));  j(sign, then_label, not_taken);  bind(&ok);}void MacroAssembler::NegativeZeroTest(Register result,                                      Register op1,                                      Register op2,                                      Register scratch,                                      Label* then_label) {  Label ok;  test(result, Operand(result));  j(not_zero, &ok, taken);  mov(scratch, Operand(op1));  or_(scratch, Operand(op2));  j(sign, then_label, not_taken);  bind(&ok);}void MacroAssembler::CallStub(CodeStub* stub) {  ASSERT(allow_stub_calls());  // calls are not allowed in some stubs  call(stub->GetCode(), RelocInfo::CODE_TARGET);}void MacroAssembler::StubReturn(int argc) {  ASSERT(argc >= 1 && generating_stub());  ret((argc - 1) * kPointerSize);}void MacroAssembler::IllegalOperation() {  push(Immediate(Factory::undefined_value()));}void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {  CallRuntime(Runtime::FunctionForId(id), num_arguments);}void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {  // If the expected number of arguments of the runtime function is  // constant, we check that the actual number of arguments match the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -