| OLD | NEW | 
|     1 // Copyright 2011 the V8 project authors. All rights reserved. |     1 // Copyright 2011 the V8 project authors. All rights reserved. | 
|     2 // Redistribution and use in source and binary forms, with or without |     2 // Redistribution and use in source and binary forms, with or without | 
|     3 // modification, are permitted provided that the following conditions are |     3 // modification, are permitted provided that the following conditions are | 
|     4 // met: |     4 // met: | 
|     5 // |     5 // | 
|     6 //     * Redistributions of source code must retain the above copyright |     6 //     * Redistributions of source code must retain the above copyright | 
|     7 //       notice, this list of conditions and the following disclaimer. |     7 //       notice, this list of conditions and the following disclaimer. | 
|     8 //     * Redistributions in binary form must reproduce the above |     8 //     * Redistributions in binary form must reproduce the above | 
|     9 //       copyright notice, this list of conditions and the following |     9 //       copyright notice, this list of conditions and the following | 
|    10 //       disclaimer in the documentation and/or other materials provided |    10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   116 //   o rdi: the JS function object being called (ie, ourselves) |   116 //   o rdi: the JS function object being called (ie, ourselves) | 
|   117 //   o rsi: our context |   117 //   o rsi: our context | 
|   118 //   o rbp: our caller's frame pointer |   118 //   o rbp: our caller's frame pointer | 
|   119 //   o rsp: stack pointer (pointing to return address) |   119 //   o rsp: stack pointer (pointing to return address) | 
|   120 // |   120 // | 
|   121 // The function builds a JS frame.  Please see JavaScriptFrameConstants in |   121 // The function builds a JS frame.  Please see JavaScriptFrameConstants in | 
|   122 // frames-x64.h for its layout. |   122 // frames-x64.h for its layout. | 
|   123 void FullCodeGenerator::Generate(CompilationInfo* info) { |   123 void FullCodeGenerator::Generate(CompilationInfo* info) { | 
|   124   ASSERT(info_ == NULL); |   124   ASSERT(info_ == NULL); | 
|   125   info_ = info; |   125   info_ = info; | 
 |   126   scope_ = info->scope(); | 
|   126   SetFunctionPosition(function()); |   127   SetFunctionPosition(function()); | 
|   127   Comment cmnt(masm_, "[ function compiled by full code generator"); |   128   Comment cmnt(masm_, "[ function compiled by full code generator"); | 
|   128  |   129  | 
|   129 #ifdef DEBUG |   130 #ifdef DEBUG | 
|   130   if (strlen(FLAG_stop_at) > 0 && |   131   if (strlen(FLAG_stop_at) > 0 && | 
|   131       info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |   132       info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 
|   132     __ int3(); |   133     __ int3(); | 
|   133   } |   134   } | 
|   134 #endif |   135 #endif | 
|   135  |   136  | 
|   136   // Strict mode functions and builtins need to replace the receiver |   137   // Strict mode functions and builtins need to replace the receiver | 
|   137   // with undefined when called as functions (without an explicit |   138   // with undefined when called as functions (without an explicit | 
|   138   // receiver object). rcx is zero for method calls and non-zero for |   139   // receiver object). rcx is zero for method calls and non-zero for | 
|   139   // function calls. |   140   // function calls. | 
|   140   if (info->is_strict_mode() || info->is_native()) { |   141   if (info->is_strict_mode() || info->is_native()) { | 
|   141     Label ok; |   142     Label ok; | 
|   142     __ testq(rcx, rcx); |   143     __ testq(rcx, rcx); | 
|   143     __ j(zero, &ok, Label::kNear); |   144     __ j(zero, &ok, Label::kNear); | 
|   144     // +1 for return address. |   145     // +1 for return address. | 
|   145     int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; |   146     int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; | 
|   146     __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |   147     __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); | 
|   147     __ movq(Operand(rsp, receiver_offset), kScratchRegister); |   148     __ movq(Operand(rsp, receiver_offset), kScratchRegister); | 
|   148     __ bind(&ok); |   149     __ bind(&ok); | 
|   149   } |   150   } | 
|   150  |   151  | 
|   151   __ push(rbp);  // Caller's frame pointer. |   152   __ push(rbp);  // Caller's frame pointer. | 
|   152   __ movq(rbp, rsp); |   153   __ movq(rbp, rsp); | 
|   153   __ push(rsi);  // Callee's context. |   154   __ push(rsi);  // Callee's context. | 
|   154   __ push(rdi);  // Callee's JS Function. |   155   __ push(rdi);  // Callee's JS Function. | 
|   155  |   156  | 
|   156   { Comment cmnt(masm_, "[ Allocate locals"); |   157   { Comment cmnt(masm_, "[ Allocate locals"); | 
|   157     int locals_count = scope()->num_stack_slots(); |   158     int locals_count = info->scope()->num_stack_slots(); | 
|   158     if (locals_count == 1) { |   159     if (locals_count == 1) { | 
|   159       __ PushRoot(Heap::kUndefinedValueRootIndex); |   160       __ PushRoot(Heap::kUndefinedValueRootIndex); | 
|   160     } else if (locals_count > 1) { |   161     } else if (locals_count > 1) { | 
|   161       __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |   162       __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 
|   162       for (int i = 0; i < locals_count; i++) { |   163       for (int i = 0; i < locals_count; i++) { | 
|   163         __ push(rdx); |   164         __ push(rdx); | 
|   164       } |   165       } | 
|   165     } |   166     } | 
|   166   } |   167   } | 
|   167  |   168  | 
|   168   bool function_in_register = true; |   169   bool function_in_register = true; | 
|   169  |   170  | 
|   170   // Possibly allocate a local context. |   171   // Possibly allocate a local context. | 
|   171   int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |   172   int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 
|   172   if (heap_slots > 0) { |   173   if (heap_slots > 0) { | 
|   173     Comment cmnt(masm_, "[ Allocate local context"); |   174     Comment cmnt(masm_, "[ Allocate local context"); | 
|   174     // Argument to NewContext is the function, which is still in rdi. |   175     // Argument to NewContext is the function, which is still in rdi. | 
|   175     __ push(rdi); |   176     __ push(rdi); | 
|   176     if (heap_slots <= FastNewContextStub::kMaximumSlots) { |   177     if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 
|   177       FastNewContextStub stub(heap_slots); |   178       FastNewContextStub stub(heap_slots); | 
|   178       __ CallStub(&stub); |   179       __ CallStub(&stub); | 
|   179     } else { |   180     } else { | 
|   180       __ CallRuntime(Runtime::kNewFunctionContext, 1); |   181       __ CallRuntime(Runtime::kNewFunctionContext, 1); | 
|   181     } |   182     } | 
|   182     function_in_register = false; |   183     function_in_register = false; | 
|   183     // Context is returned in both rax and rsi.  It replaces the context |   184     // Context is returned in both rax and rsi.  It replaces the context | 
|   184     // passed to us.  It's saved in the stack and kept live in rsi. |   185     // passed to us.  It's saved in the stack and kept live in rsi. | 
|   185     __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); |   186     __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); | 
|   186  |   187  | 
|   187     // Copy any necessary parameters into the context. |   188     // Copy any necessary parameters into the context. | 
|   188     int num_parameters = scope()->num_parameters(); |   189     int num_parameters = info->scope()->num_parameters(); | 
|   189     for (int i = 0; i < num_parameters; i++) { |   190     for (int i = 0; i < num_parameters; i++) { | 
|   190       Slot* slot = scope()->parameter(i)->AsSlot(); |   191       Slot* slot = scope()->parameter(i)->AsSlot(); | 
|   191       if (slot != NULL && slot->type() == Slot::CONTEXT) { |   192       if (slot != NULL && slot->type() == Slot::CONTEXT) { | 
|   192         int parameter_offset = StandardFrameConstants::kCallerSPOffset + |   193         int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 
|   193             (num_parameters - 1 - i) * kPointerSize; |   194             (num_parameters - 1 - i) * kPointerSize; | 
|   194         // Load parameter from stack. |   195         // Load parameter from stack. | 
|   195         __ movq(rax, Operand(rbp, parameter_offset)); |   196         __ movq(rax, Operand(rbp, parameter_offset)); | 
|   196         // Store it in the context. |   197         // Store it in the context. | 
|   197         int context_offset = Context::SlotOffset(slot->index()); |   198         int context_offset = Context::SlotOffset(slot->index()); | 
|   198         __ movq(Operand(rsi, context_offset), rax); |   199         __ movq(Operand(rsi, context_offset), rax); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   210   if (arguments != NULL) { |   211   if (arguments != NULL) { | 
|   211     // Arguments object must be allocated after the context object, in |   212     // Arguments object must be allocated after the context object, in | 
|   212     // case the "arguments" or ".arguments" variables are in the context. |   213     // case the "arguments" or ".arguments" variables are in the context. | 
|   213     Comment cmnt(masm_, "[ Allocate arguments object"); |   214     Comment cmnt(masm_, "[ Allocate arguments object"); | 
|   214     if (function_in_register) { |   215     if (function_in_register) { | 
|   215       __ push(rdi); |   216       __ push(rdi); | 
|   216     } else { |   217     } else { | 
|   217       __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |   218       __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 
|   218     } |   219     } | 
|   219     // The receiver is just before the parameters on the caller's stack. |   220     // The receiver is just before the parameters on the caller's stack. | 
|   220     int offset = scope()->num_parameters() * kPointerSize; |   221     int num_parameters = info->scope()->num_parameters(); | 
 |   222     int offset = num_parameters * kPointerSize; | 
|   221     __ lea(rdx, |   223     __ lea(rdx, | 
|   222            Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); |   224            Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); | 
|   223     __ push(rdx); |   225     __ push(rdx); | 
|   224     __ Push(Smi::FromInt(scope()->num_parameters())); |   226     __ Push(Smi::FromInt(num_parameters)); | 
|   225     // Arguments to ArgumentsAccessStub: |   227     // Arguments to ArgumentsAccessStub: | 
|   226     //   function, receiver address, parameter count. |   228     //   function, receiver address, parameter count. | 
|   227     // The stub will rewrite receiver and parameter count if the previous |   229     // The stub will rewrite receiver and parameter count if the previous | 
|   228     // stack frame was an arguments adapter frame. |   230     // stack frame was an arguments adapter frame. | 
|   229     ArgumentsAccessStub stub( |   231     ArgumentsAccessStub stub( | 
|   230         is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT |   232         is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT | 
|   231                          : ArgumentsAccessStub::NEW_NON_STRICT_SLOW); |   233                          : ArgumentsAccessStub::NEW_NON_STRICT_SLOW); | 
|   232     __ CallStub(&stub); |   234     __ CallStub(&stub); | 
|   233  |   235  | 
|   234     Move(arguments->AsSlot(), rax, rbx, rdx); |   236     Move(arguments->AsSlot(), rax, rbx, rdx); | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   327     Label check_exit_codesize; |   329     Label check_exit_codesize; | 
|   328     masm_->bind(&check_exit_codesize); |   330     masm_->bind(&check_exit_codesize); | 
|   329 #endif |   331 #endif | 
|   330     CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); |   332     CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 
|   331     __ RecordJSReturn(); |   333     __ RecordJSReturn(); | 
|   332     // Do not use the leave instruction here because it is too short to |   334     // Do not use the leave instruction here because it is too short to | 
|   333     // patch with the code required by the debugger. |   335     // patch with the code required by the debugger. | 
|   334     __ movq(rsp, rbp); |   336     __ movq(rsp, rbp); | 
|   335     __ pop(rbp); |   337     __ pop(rbp); | 
|   336  |   338  | 
|   337     int arguments_bytes = (scope()->num_parameters() + 1) * kPointerSize; |   339     int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize; | 
|   338     __ Ret(arguments_bytes, rcx); |   340     __ Ret(arguments_bytes, rcx); | 
|   339  |   341  | 
|   340 #ifdef ENABLE_DEBUGGER_SUPPORT |   342 #ifdef ENABLE_DEBUGGER_SUPPORT | 
|   341     // Add padding that will be overwritten by a debugger breakpoint.  We |   343     // Add padding that will be overwritten by a debugger breakpoint.  We | 
|   342     // have just generated at least 7 bytes: "movq rsp, rbp; pop rbp; ret k" |   344     // have just generated at least 7 bytes: "movq rsp, rbp; pop rbp; ret k" | 
|   343     // (3 + 1 + 3). |   345     // (3 + 1 + 3). | 
|   344     const int kPadding = Assembler::kJSReturnSequenceLength - 7; |   346     const int kPadding = Assembler::kJSReturnSequenceLength - 7; | 
|   345     for (int i = 0; i < kPadding; ++i) { |   347     for (int i = 0; i < kPadding; ++i) { | 
|   346       masm_->int3(); |   348       masm_->int3(); | 
|   347     } |   349     } | 
| (...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2018 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, |  2020 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, | 
|  2019                                                       int arg_count) { |  2021                                                       int arg_count) { | 
|  2020   // Push copy of the first argument or undefined if it doesn't exist. |  2022   // Push copy of the first argument or undefined if it doesn't exist. | 
|  2021   if (arg_count > 0) { |  2023   if (arg_count > 0) { | 
|  2022     __ push(Operand(rsp, arg_count * kPointerSize)); |  2024     __ push(Operand(rsp, arg_count * kPointerSize)); | 
|  2023   } else { |  2025   } else { | 
|  2024     __ PushRoot(Heap::kUndefinedValueRootIndex); |  2026     __ PushRoot(Heap::kUndefinedValueRootIndex); | 
|  2025   } |  2027   } | 
|  2026  |  2028  | 
|  2027   // Push the receiver of the enclosing function and do runtime call. |  2029   // Push the receiver of the enclosing function and do runtime call. | 
|  2028   __ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize)); |  2030   __ push(Operand(rbp, (2 + info_->scope()->num_parameters()) * kPointerSize)); | 
|  2029  |  2031  | 
|  2030   // Push the strict mode flag. |  2032   // Push the strict mode flag. | 
|  2031   __ Push(Smi::FromInt(strict_mode_flag())); |  2033   __ Push(Smi::FromInt(strict_mode_flag())); | 
|  2032  |  2034  | 
|  2033   __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP |  2035   __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP | 
|  2034                  ? Runtime::kResolvePossiblyDirectEvalNoLookup |  2036                  ? Runtime::kResolvePossiblyDirectEvalNoLookup | 
|  2035                  : Runtime::kResolvePossiblyDirectEval, 4); |  2037                  : Runtime::kResolvePossiblyDirectEval, 4); | 
|  2036 } |  2038 } | 
|  2037  |  2039  | 
|  2038  |  2040  | 
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2560 } |  2562 } | 
|  2561  |  2563  | 
|  2562  |  2564  | 
|  2563 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { |  2565 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { | 
|  2564   ASSERT(args->length() == 1); |  2566   ASSERT(args->length() == 1); | 
|  2565  |  2567  | 
|  2566   // ArgumentsAccessStub expects the key in rdx and the formal |  2568   // ArgumentsAccessStub expects the key in rdx and the formal | 
|  2567   // parameter count in rax. |  2569   // parameter count in rax. | 
|  2568   VisitForAccumulatorValue(args->at(0)); |  2570   VisitForAccumulatorValue(args->at(0)); | 
|  2569   __ movq(rdx, rax); |  2571   __ movq(rdx, rax); | 
|  2570   __ Move(rax, Smi::FromInt(scope()->num_parameters())); |  2572   __ Move(rax, Smi::FromInt(info_->scope()->num_parameters())); | 
|  2571   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |  2573   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 
|  2572   __ CallStub(&stub); |  2574   __ CallStub(&stub); | 
|  2573   context()->Plug(rax); |  2575   context()->Plug(rax); | 
|  2574 } |  2576 } | 
|  2575  |  2577  | 
|  2576  |  2578  | 
|  2577 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { |  2579 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { | 
|  2578   ASSERT(args->length() == 0); |  2580   ASSERT(args->length() == 0); | 
|  2579  |  2581  | 
|  2580   Label exit; |  2582   Label exit; | 
|  2581   // Get the number of formal parameters. |  2583   // Get the number of formal parameters. | 
|  2582   __ Move(rax, Smi::FromInt(scope()->num_parameters())); |  2584   __ Move(rax, Smi::FromInt(info_->scope()->num_parameters())); | 
|  2583  |  2585  | 
|  2584   // Check if the calling frame is an arguments adaptor frame. |  2586   // Check if the calling frame is an arguments adaptor frame. | 
|  2585   __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  2587   __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
|  2586   __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset), |  2588   __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset), | 
|  2587          Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  2589          Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
|  2588   __ j(not_equal, &exit, Label::kNear); |  2590   __ j(not_equal, &exit, Label::kNear); | 
|  2589  |  2591  | 
|  2590   // Arguments adaptor case: Read the arguments length from the |  2592   // Arguments adaptor case: Read the arguments length from the | 
|  2591   // adaptor frame. |  2593   // adaptor frame. | 
|  2592   __ movq(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |  2594   __ movq(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
| (...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4159     // as their closure, not the anonymous closure containing the global |  4161     // as their closure, not the anonymous closure containing the global | 
|  4160     // code.  Pass a smi sentinel and let the runtime look up the empty |  4162     // code.  Pass a smi sentinel and let the runtime look up the empty | 
|  4161     // function. |  4163     // function. | 
|  4162     __ Push(Smi::FromInt(0)); |  4164     __ Push(Smi::FromInt(0)); | 
|  4163   } else if (scope()->is_eval_scope()) { |  4165   } else if (scope()->is_eval_scope()) { | 
|  4164     // Contexts created by a call to eval have the same closure as the |  4166     // Contexts created by a call to eval have the same closure as the | 
|  4165     // context calling eval, not the anonymous closure containing the eval |  4167     // context calling eval, not the anonymous closure containing the eval | 
|  4166     // code.  Fetch it from the context. |  4168     // code.  Fetch it from the context. | 
|  4167     __ push(ContextOperand(rsi, Context::CLOSURE_INDEX)); |  4169     __ push(ContextOperand(rsi, Context::CLOSURE_INDEX)); | 
|  4168   } else { |  4170   } else { | 
|  4169     ASSERT(scope()->is_function_scope()); |  4171     ASSERT(scope()->is_function_scope() || scope()->is_catch_scope()); | 
|  4170     __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |  4172     __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 
|  4171   } |  4173   } | 
|  4172 } |  4174 } | 
|  4173  |  4175  | 
|  4174  |  4176  | 
|  4175 // ---------------------------------------------------------------------------- |  4177 // ---------------------------------------------------------------------------- | 
|  4176 // Non-local control flow support. |  4178 // Non-local control flow support. | 
|  4177  |  4179  | 
|  4178  |  4180  | 
|  4179 void FullCodeGenerator::EnterFinallyBlock() { |  4181 void FullCodeGenerator::EnterFinallyBlock() { | 
|  4180   ASSERT(!result_register().is(rdx)); |  4182   ASSERT(!result_register().is(rdx)); | 
|  4181   ASSERT(!result_register().is(rcx)); |  4183   ASSERT(!result_register().is(rcx)); | 
|  4182   // Cook return address on top of stack (smi encoded Code* delta) |  4184   // Cook return address on top of stack (smi encoded Code* delta) | 
|  4183   __ movq(rdx, Operand(rsp, 0)); |  4185   __ pop(rdx); | 
|  4184   __ Move(rcx, masm_->CodeObject()); |  4186   __ Move(rcx, masm_->CodeObject()); | 
|  4185   __ subq(rdx, rcx); |  4187   __ subq(rdx, rcx); | 
|  4186   __ Integer32ToSmi(rdx, rdx); |  4188   __ Integer32ToSmi(rdx, rdx); | 
|  4187   __ movq(Operand(rsp, 0), rdx); |  4189   __ push(rdx); | 
|  4188   // Store result register while executing finally block. |  4190   // Store result register while executing finally block. | 
|  4189   __ push(result_register()); |  4191   __ push(result_register()); | 
|  4190 } |  4192 } | 
|  4191  |  4193  | 
|  4192  |  4194  | 
|  4193 void FullCodeGenerator::ExitFinallyBlock() { |  4195 void FullCodeGenerator::ExitFinallyBlock() { | 
|  4194   ASSERT(!result_register().is(rdx)); |  4196   ASSERT(!result_register().is(rdx)); | 
|  4195   ASSERT(!result_register().is(rcx)); |  4197   ASSERT(!result_register().is(rcx)); | 
|  4196   // Restore result register from stack. |  | 
|  4197   __ pop(result_register()); |  4198   __ pop(result_register()); | 
|  4198   // Uncook return address. |  4199   // Uncook return address. | 
|  4199   __ movq(rdx, Operand(rsp, 0)); |  4200   __ pop(rdx); | 
|  4200   __ SmiToInteger32(rdx, rdx); |  4201   __ SmiToInteger32(rdx, rdx); | 
|  4201   __ Move(rcx, masm_->CodeObject()); |  4202   __ Move(rcx, masm_->CodeObject()); | 
|  4202   __ addq(rdx, rcx); |  4203   __ addq(rdx, rcx); | 
|  4203   __ movq(Operand(rsp, 0), rdx); |  4204   __ jmp(rdx); | 
|  4204   // And return. |  | 
|  4205   __ ret(0); |  | 
|  4206 } |  4205 } | 
|  4207  |  4206  | 
|  4208  |  4207  | 
|  4209 #undef __ |  4208 #undef __ | 
|  4210  |  4209  | 
|  4211  |  4210  | 
|  4212 } }  // namespace v8::internal |  4211 } }  // namespace v8::internal | 
|  4213  |  4212  | 
|  4214 #endif  // V8_TARGET_ARCH_X64 |  4213 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |