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

📄 builtins-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
  // Use inline caching to speed up access to arguments.  Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));  __ call(ic, RelocInfo::CODE_TARGET);  // Remove IC arguments from the stack and push the nth argument.  __ add(Operand(esp), Immediate(2 * kPointerSize));  __ push(eax);  // Update the index on the stack and in register eax.  __ mov(eax, Operand(ebp, kIndexOffset));  __ add(Operand(eax), Immediate(1 << kSmiTagSize));  __ mov(Operand(ebp, kIndexOffset), eax);  __ bind(&entry);  __ cmp(eax, Operand(ebp, kLimitOffset));  __ j(not_equal, &loop);  // Invoke the function.  ParameterCount actual(eax);  __ shr(eax, kSmiTagSize);  __ mov(edi, Operand(ebp, 4 * kPointerSize));  __ InvokeFunction(edi, actual, CALL_FUNCTION);  __ LeaveInternalFrame();  __ ret(3 * kPointerSize);  // remove this, receiver, and arguments}static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {  __ push(ebp);  __ mov(ebp, Operand(esp));  // Store the arguments adaptor context sentinel.  __ push(Immediate(ArgumentsAdaptorFrame::SENTINEL));  // Push the function on the stack.  __ push(edi);  // Preserve the number of arguments on the stack. Must preserve both  // eax and ebx because these registers are used when copying the  // arguments and the receiver.  ASSERT(kSmiTagSize == 1);  __ lea(ecx, Operand(eax, eax, times_1, kSmiTag));  __ push(Operand(ecx));}static void ExitArgumentsAdaptorFrame(MacroAssembler* masm) {  // Retrieve the number of arguments from the stack.  __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));  // Leave the frame.  __ leave();  // Remove caller arguments from the stack.  ASSERT(kSmiTagSize == 1 && kSmiTag == 0);  __ pop(ecx);  __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver  __ push(ecx);}void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- eax : actual number of arguments  //  -- ebx : expected number of arguments  //  -- edx : code entry to call  // -----------------------------------  Label invoke, dont_adapt_arguments;  __ IncrementCounter(&Counters::arguments_adaptors, 1);  Label enough, too_few;  __ cmp(eax, Operand(ebx));  __ j(less, &too_few);  __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);  __ j(equal, &dont_adapt_arguments);  {  // Enough parameters: Actual >= expected.    __ bind(&enough);    EnterArgumentsAdaptorFrame(masm);    // Copy receiver and all expected arguments.    const int offset = StandardFrameConstants::kCallerSPOffset;    __ lea(eax, Operand(ebp, eax, times_4, offset));    __ mov(ecx, -1);  // account for receiver    Label copy;    __ bind(&copy);    __ inc(ecx);    __ push(Operand(eax, 0));    __ sub(Operand(eax), Immediate(kPointerSize));    __ cmp(ecx, Operand(ebx));    __ j(less, &copy);    __ jmp(&invoke);  }  {  // Too few parameters: Actual < expected.    __ bind(&too_few);    EnterArgumentsAdaptorFrame(masm);    // Copy receiver and all actual arguments.    const int offset = StandardFrameConstants::kCallerSPOffset;    __ lea(edi, Operand(ebp, eax, times_4, offset));    __ mov(ecx, -1);  // account for receiver    Label copy;    __ bind(&copy);    __ inc(ecx);    __ push(Operand(edi, 0));    __ sub(Operand(edi), Immediate(kPointerSize));    __ cmp(ecx, Operand(eax));    __ j(less, &copy);    // Fill remaining expected arguments with undefined values.    Label fill;    __ bind(&fill);    __ inc(ecx);    __ push(Immediate(Factory::undefined_value()));    __ cmp(ecx, Operand(ebx));    __ j(less, &fill);    // Restore function pointer.    __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));  }  // Call the entry point.  Label return_site;  __ bind(&invoke);  __ call(Operand(edx));  __ bind(&return_site);  ExitArgumentsAdaptorFrame(masm);  __ ret(0);  // Compute the offset from the beginning of the ArgumentsAdaptorTrampoline  // builtin code object to the return address after the call.  ASSERT(return_site.is_bound());  arguments_adaptor_call_pc_offset_ = return_site.pos() + Code::kHeaderSize;  // -------------------------------------------  // Dont adapt arguments.  // -------------------------------------------  __ bind(&dont_adapt_arguments);  __ jmp(Operand(edx));}static void Generate_DebugBreakCallHelper(MacroAssembler* masm,                                          RegList pointer_regs,                                          bool convert_call_to_jmp) {  // Save the content of all general purpose registers in memory. This copy in  // memory is later pushed onto the JS expression stack for the fake JS frame  // generated and also to the C frame generated on top of that. In the JS  // frame ONLY the registers containing pointers will be pushed on the  // expression stack. This causes the GC to update these pointers so that  // they will have the correct value when returning from the debugger.  __ SaveRegistersToMemory(kJSCallerSaved);  // Enter an internal frame.  __ EnterInternalFrame();  // Store the registers containing object pointers on the expression stack to  // make sure that these are correctly updated during GC.  __ PushRegistersFromMemory(pointer_regs);#ifdef DEBUG  __ RecordComment("// Calling from debug break to runtime - come in - over");#endif  __ Set(eax, Immediate(0));  // no arguments  __ mov(Operand(ebx), Immediate(ExternalReference::debug_break()));  CEntryDebugBreakStub ceb;  __ CallStub(&ceb);  // Restore the register values containing object pointers from the expression  // stack in the reverse order as they where pushed.  __ PopRegistersToMemory(pointer_regs);  // Get rid of the internal frame.  __ LeaveInternalFrame();  // If this call did not replace a call but patched other code then there will  // be an unwanted return address left on the stack. Here we get rid of that.  if (convert_call_to_jmp) {    __ pop(eax);  }  // Finally restore all registers.  __ RestoreRegistersFromMemory(kJSCallerSaved);  // Now that the break point has been handled, resume normal execution by  // jumping to the target address intended by the caller and that was  // overwritten by the address of DebugBreakXXX.  ExternalReference after_break_target =      ExternalReference(Debug_Address::AfterBreakTarget());  __ jmp(Operand::StaticVariable(after_break_target));}void Builtins::Generate_LoadIC_DebugBreak(MacroAssembler* masm) {  // Register state for IC load call (from ic-ia32.cc).  // ----------- S t a t e -------------  //  -- ecx    : name  // -----------------------------------  Generate_DebugBreakCallHelper(masm, ecx.bit(), false);}void Builtins::Generate_StoreIC_DebugBreak(MacroAssembler* masm) {  // REgister state for IC store call (from ic-ia32.cc).  // ----------- S t a t e -------------  //  -- eax    : value  //  -- ecx    : name  // -----------------------------------  Generate_DebugBreakCallHelper(masm, eax.bit() | ecx.bit(), false);}void Builtins::Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {  // Register state for keyed IC load call (from ic-ia32.cc).  // ----------- S t a t e -------------  //  No registers used on entry.  // -----------------------------------  Generate_DebugBreakCallHelper(masm, 0, false);}void Builtins::Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {  // Register state for keyed IC load call (from ic-ia32.cc).  // ----------- S t a t e -------------  //  -- eax    : value  // -----------------------------------  // Register eax contains an object that needs to be pushed on the  // expression stack of the fake JS frame.  Generate_DebugBreakCallHelper(masm, eax.bit(), false);}void Builtins::Generate_CallIC_DebugBreak(MacroAssembler* masm) {  // Register state for keyed IC call call (from ic-ia32.cc)  // ----------- S t a t e -------------  //  -- eax: number of arguments  // -----------------------------------  // The number of arguments in eax is not smi encoded.  Generate_DebugBreakCallHelper(masm, 0, false);}void Builtins::Generate_ConstructCall_DebugBreak(MacroAssembler* masm) {  // Register state just before return from JS function (from codegen-ia32.cc).  // eax is the actual number of arguments not encoded as a smi see comment  // above IC call.  // ----------- S t a t e -------------  //  -- eax: number of arguments  // -----------------------------------  // The number of arguments in eax is not smi encoded.  Generate_DebugBreakCallHelper(masm, 0, false);}void Builtins::Generate_Return_DebugBreak(MacroAssembler* masm) {  // Register state just before return from JS function (from codegen-ia32.cc).  // ----------- S t a t e -------------  //  -- eax: return value  // -----------------------------------  Generate_DebugBreakCallHelper(masm, eax.bit(), true);}void Builtins::Generate_Return_DebugBreakEntry(MacroAssembler* masm) {  // OK to clobber ebx as we are returning from a JS function in the code  // generated by Ia32CodeGenerator::ExitJSFrame.  ExternalReference debug_break_return =      ExternalReference(Debug_Address::DebugBreakReturn());  __ mov(ebx, Operand::StaticVariable(debug_break_return));  __ add(Operand(ebx), Immediate(Code::kHeaderSize - kHeapObjectTag));  __ jmp(Operand(ebx));}void Builtins::Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) {  // Register state for stub CallFunction (from CallFunctionStub in ic-ia32.cc).  // ----------- S t a t e -------------  //  No registers used on entry.  // -----------------------------------  Generate_DebugBreakCallHelper(masm, 0, false);}#undef __} }  // namespace v8::internal

⌨️ 快捷键说明

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