| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #if V8_TARGET_ARCH_X64 |     5 #if V8_TARGET_ARCH_X64 | 
|     6  |     6  | 
|     7 #include "src/base/bits.h" |     7 #include "src/base/bits.h" | 
|     8 #include "src/base/division-by-constant.h" |     8 #include "src/base/division-by-constant.h" | 
|     9 #include "src/bootstrapper.h" |     9 #include "src/bootstrapper.h" | 
|    10 #include "src/codegen.h" |    10 #include "src/codegen.h" | 
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   701  |   701  | 
|   702 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, |   702 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, | 
|   703                                    const CallWrapper& call_wrapper) { |   703                                    const CallWrapper& call_wrapper) { | 
|   704   // You can't call a builtin without a valid frame. |   704   // You can't call a builtin without a valid frame. | 
|   705   DCHECK(flag == JUMP_FUNCTION || has_frame()); |   705   DCHECK(flag == JUMP_FUNCTION || has_frame()); | 
|   706  |   706  | 
|   707   // Rely on the assertion to check that the number of provided |   707   // Rely on the assertion to check that the number of provided | 
|   708   // arguments match the expected number of arguments. Fake a |   708   // arguments match the expected number of arguments. Fake a | 
|   709   // parameter count to avoid emitting code to do the check. |   709   // parameter count to avoid emitting code to do the check. | 
|   710   ParameterCount expected(0); |   710   ParameterCount expected(0); | 
|   711   GetBuiltinFunction(rdi, native_context_index); |   711   LoadNativeContextSlot(native_context_index, rdi); | 
|   712   InvokeFunctionCode(rdi, no_reg, expected, expected, flag, call_wrapper); |   712   InvokeFunctionCode(rdi, no_reg, expected, expected, flag, call_wrapper); | 
|   713 } |   713 } | 
|   714  |   714  | 
|   715  |   715  | 
|   716 void MacroAssembler::GetBuiltinFunction(Register target, |  | 
|   717                                         int native_context_index) { |  | 
|   718   // Load the builtins object into target register. |  | 
|   719   movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  | 
|   720   movp(target, FieldOperand(target, JSGlobalObject::kNativeContextOffset)); |  | 
|   721   movp(target, ContextOperand(target, native_context_index)); |  | 
|   722 } |  | 
|   723  |  | 
|   724  |  | 
|   725 #define REG(Name) \ |   716 #define REG(Name) \ | 
|   726   { Register::kCode_##Name } |   717   { Register::kCode_##Name } | 
|   727  |   718  | 
|   728 static const Register saved_regs[] = { |   719 static const Register saved_regs[] = { | 
|   729   REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), |   720   REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), | 
|   730   REG(r9), REG(r10), REG(r11) |   721   REG(r9), REG(r10), REG(r11) | 
|   731 }; |   722 }; | 
|   732  |   723  | 
|   733 #undef REG |   724 #undef REG | 
|   734  |   725  | 
| (...skipping 3671 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4406   DCHECK(!scratch.is(kScratchRegister)); |  4397   DCHECK(!scratch.is(kScratchRegister)); | 
|  4407   // Load current lexical context from the stack frame. |  4398   // Load current lexical context from the stack frame. | 
|  4408   movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); |  4399   movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  4409  |  4400  | 
|  4410   // When generating debug code, make sure the lexical context is set. |  4401   // When generating debug code, make sure the lexical context is set. | 
|  4411   if (emit_debug_code()) { |  4402   if (emit_debug_code()) { | 
|  4412     cmpp(scratch, Immediate(0)); |  4403     cmpp(scratch, Immediate(0)); | 
|  4413     Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); |  4404     Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); | 
|  4414   } |  4405   } | 
|  4415   // Load the native context of the current context. |  4406   // Load the native context of the current context. | 
|  4416   int offset = |  4407   movp(scratch, ContextOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); | 
|  4417       Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; |  | 
|  4418   movp(scratch, FieldOperand(scratch, offset)); |  | 
|  4419   movp(scratch, FieldOperand(scratch, JSGlobalObject::kNativeContextOffset)); |  | 
|  4420  |  4408  | 
|  4421   // Check the context is a native context. |  4409   // Check the context is a native context. | 
|  4422   if (emit_debug_code()) { |  4410   if (emit_debug_code()) { | 
|  4423     Cmp(FieldOperand(scratch, HeapObject::kMapOffset), |  4411     Cmp(FieldOperand(scratch, HeapObject::kMapOffset), | 
|  4424         isolate()->factory()->native_context_map()); |  4412         isolate()->factory()->native_context_map()); | 
|  4425     Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); |  4413     Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); | 
|  4426   } |  4414   } | 
|  4427  |  4415  | 
|  4428   // Check if both contexts are the same. |  4416   // Check if both contexts are the same. | 
|  4429   cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); |  4417   cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); | 
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5065   // not agree).  A variable occurring in such a scope should have |  5053   // not agree).  A variable occurring in such a scope should have | 
|  5066   // slot type LOOKUP and not CONTEXT. |  5054   // slot type LOOKUP and not CONTEXT. | 
|  5067   if (emit_debug_code()) { |  5055   if (emit_debug_code()) { | 
|  5068     CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), |  5056     CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), | 
|  5069                 Heap::kWithContextMapRootIndex); |  5057                 Heap::kWithContextMapRootIndex); | 
|  5070     Check(not_equal, kVariableResolvedToWithContext); |  5058     Check(not_equal, kVariableResolvedToWithContext); | 
|  5071   } |  5059   } | 
|  5072 } |  5060 } | 
|  5073  |  5061  | 
|  5074  |  5062  | 
|  5075 void MacroAssembler::LoadGlobalProxy(Register dst) { |  | 
|  5076   movp(dst, GlobalObjectOperand()); |  | 
|  5077   movp(dst, FieldOperand(dst, JSGlobalObject::kGlobalProxyOffset)); |  | 
|  5078 } |  | 
|  5079  |  | 
|  5080  |  | 
|  5081 void MacroAssembler::LoadTransitionedArrayMapConditional( |  5063 void MacroAssembler::LoadTransitionedArrayMapConditional( | 
|  5082     ElementsKind expected_kind, |  5064     ElementsKind expected_kind, | 
|  5083     ElementsKind transitioned_kind, |  5065     ElementsKind transitioned_kind, | 
|  5084     Register map_in_out, |  5066     Register map_in_out, | 
|  5085     Register scratch, |  5067     Register scratch, | 
|  5086     Label* no_map_match) { |  5068     Label* no_map_match) { | 
|  5087   // Load the global or builtins object from the current context. |  | 
|  5088   movp(scratch, |  | 
|  5089        Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  | 
|  5090   movp(scratch, FieldOperand(scratch, JSGlobalObject::kNativeContextOffset)); |  | 
|  5091  |  | 
|  5092   // Check that the function's map is the same as the expected cached map. |  5069   // Check that the function's map is the same as the expected cached map. | 
|  5093   movp(scratch, Operand(scratch, |  5070   LoadNativeContextSlot(Context::JS_ARRAY_MAPS_INDEX, scratch); | 
|  5094                         Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); |  | 
|  5095  |  5071  | 
|  5096   int offset = expected_kind * kPointerSize + |  5072   int offset = expected_kind * kPointerSize + | 
|  5097       FixedArrayBase::kHeaderSize; |  5073       FixedArrayBase::kHeaderSize; | 
|  5098   cmpp(map_in_out, FieldOperand(scratch, offset)); |  5074   cmpp(map_in_out, FieldOperand(scratch, offset)); | 
|  5099   j(not_equal, no_map_match); |  5075   j(not_equal, no_map_match); | 
|  5100  |  5076  | 
|  5101   // Use the transitioned cached map. |  5077   // Use the transitioned cached map. | 
|  5102   offset = transitioned_kind * kPointerSize + |  5078   offset = transitioned_kind * kPointerSize + | 
|  5103       FixedArrayBase::kHeaderSize; |  5079       FixedArrayBase::kHeaderSize; | 
|  5104   movp(map_in_out, FieldOperand(scratch, offset)); |  5080   movp(map_in_out, FieldOperand(scratch, offset)); | 
|  5105 } |  5081 } | 
|  5106  |  5082  | 
|  5107  |  5083  | 
|  5108 #ifdef _WIN64 |  5084 #ifdef _WIN64 | 
|  5109 static const int kRegisterPassedArguments = 4; |  5085 static const int kRegisterPassedArguments = 4; | 
|  5110 #else |  5086 #else | 
|  5111 static const int kRegisterPassedArguments = 6; |  5087 static const int kRegisterPassedArguments = 6; | 
|  5112 #endif |  5088 #endif | 
|  5113  |  5089  | 
|  5114 void MacroAssembler::LoadGlobalFunction(int index, Register function) { |  5090  | 
|  5115   // Load the global or builtins object from the current context. |  5091 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { | 
|  5116   movp(function, |  5092   movp(dst, NativeContextOperand()); | 
|  5117        Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  5093   movp(dst, ContextOperand(dst, index)); | 
|  5118   // Load the native context from the global or builtins object. |  | 
|  5119   movp(function, FieldOperand(function, JSGlobalObject::kNativeContextOffset)); |  | 
|  5120   // Load the function from the native context. |  | 
|  5121   movp(function, Operand(function, Context::SlotOffset(index))); |  | 
|  5122 } |  5094 } | 
|  5123  |  5095  | 
|  5124  |  5096  | 
|  5125 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |  5097 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 
|  5126                                                   Register map) { |  5098                                                   Register map) { | 
|  5127   // Load the initial map.  The global functions all have initial maps. |  5099   // Load the initial map.  The global functions all have initial maps. | 
|  5128   movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |  5100   movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 
|  5129   if (emit_debug_code()) { |  5101   if (emit_debug_code()) { | 
|  5130     Label ok, fail; |  5102     Label ok, fail; | 
|  5131     CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); |  5103     CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); | 
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5582   movl(rax, dividend); |  5554   movl(rax, dividend); | 
|  5583   shrl(rax, Immediate(31)); |  5555   shrl(rax, Immediate(31)); | 
|  5584   addl(rdx, rax); |  5556   addl(rdx, rax); | 
|  5585 } |  5557 } | 
|  5586  |  5558  | 
|  5587  |  5559  | 
|  5588 }  // namespace internal |  5560 }  // namespace internal | 
|  5589 }  // namespace v8 |  5561 }  // namespace v8 | 
|  5590  |  5562  | 
|  5591 #endif  // V8_TARGET_ARCH_X64 |  5563 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |