| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 11 #include "src/code-stubs.h" |
| 11 #include "src/hydrogen-osr.h" | 12 #include "src/hydrogen-osr.h" |
| 12 #include "src/ic/stub-cache.h" | 13 #include "src/ic/stub-cache.h" |
| 13 #include "src/x64/lithium-codegen-x64.h" | 14 #include "src/x64/lithium-codegen-x64.h" |
| 14 | 15 |
| 15 namespace v8 { | 16 namespace v8 { |
| 16 namespace internal { | 17 namespace internal { |
| 17 | 18 |
| 18 | 19 |
| 19 // When invoking builtins, we need to record the safepoint in the middle of | 20 // When invoking builtins, we need to record the safepoint in the middle of |
| (...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 } | 2052 } |
| 2052 } | 2053 } |
| 2053 | 2054 |
| 2054 | 2055 |
| 2055 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 2056 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
| 2056 DCHECK(ToRegister(instr->context()).is(rsi)); | 2057 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 2057 DCHECK(ToRegister(instr->left()).is(rdx)); | 2058 DCHECK(ToRegister(instr->left()).is(rdx)); |
| 2058 DCHECK(ToRegister(instr->right()).is(rax)); | 2059 DCHECK(ToRegister(instr->right()).is(rax)); |
| 2059 DCHECK(ToRegister(instr->result()).is(rax)); | 2060 DCHECK(ToRegister(instr->result()).is(rax)); |
| 2060 | 2061 |
| 2061 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 2062 Handle<Code> code = |
| 2062 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 2063 CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code(); |
| 2064 CallCode(code, RelocInfo::CODE_TARGET, instr); |
| 2063 } | 2065 } |
| 2064 | 2066 |
| 2065 | 2067 |
| 2066 template<class InstrType> | 2068 template<class InstrType> |
| 2067 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { | 2069 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { |
| 2068 int left_block = instr->TrueDestination(chunk_); | 2070 int left_block = instr->TrueDestination(chunk_); |
| 2069 int right_block = instr->FalseDestination(chunk_); | 2071 int right_block = instr->FalseDestination(chunk_); |
| 2070 | 2072 |
| 2071 int next_block = GetNextEmittedBlock(); | 2073 int next_block = GetNextEmittedBlock(); |
| 2072 | 2074 |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2494 __ testb(FieldOperand(temp, Map::kBitFieldOffset), | 2496 __ testb(FieldOperand(temp, Map::kBitFieldOffset), |
| 2495 Immediate(1 << Map::kIsUndetectable)); | 2497 Immediate(1 << Map::kIsUndetectable)); |
| 2496 EmitBranch(instr, not_zero); | 2498 EmitBranch(instr, not_zero); |
| 2497 } | 2499 } |
| 2498 | 2500 |
| 2499 | 2501 |
| 2500 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { | 2502 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { |
| 2501 DCHECK(ToRegister(instr->context()).is(rsi)); | 2503 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 2502 Token::Value op = instr->op(); | 2504 Token::Value op = instr->op(); |
| 2503 | 2505 |
| 2504 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 2506 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); |
| 2505 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2507 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2506 | 2508 |
| 2507 Condition condition = TokenToCondition(op, false); | 2509 Condition condition = TokenToCondition(op, false); |
| 2508 __ testp(rax, rax); | 2510 __ testp(rax, rax); |
| 2509 | 2511 |
| 2510 EmitBranch(instr, condition); | 2512 EmitBranch(instr, condition); |
| 2511 } | 2513 } |
| 2512 | 2514 |
| 2513 | 2515 |
| 2514 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { | 2516 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2778 __ bind(&load_false); | 2780 __ bind(&load_false); |
| 2779 __ LoadRoot(rax, Heap::kFalseValueRootIndex); | 2781 __ LoadRoot(rax, Heap::kFalseValueRootIndex); |
| 2780 __ bind(&done); | 2782 __ bind(&done); |
| 2781 } | 2783 } |
| 2782 | 2784 |
| 2783 | 2785 |
| 2784 void LCodeGen::DoCmpT(LCmpT* instr) { | 2786 void LCodeGen::DoCmpT(LCmpT* instr) { |
| 2785 DCHECK(ToRegister(instr->context()).is(rsi)); | 2787 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 2786 Token::Value op = instr->op(); | 2788 Token::Value op = instr->op(); |
| 2787 | 2789 |
| 2788 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 2790 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); |
| 2789 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2791 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2790 | 2792 |
| 2791 Condition condition = TokenToCondition(op, false); | 2793 Condition condition = TokenToCondition(op, false); |
| 2792 Label true_value, done; | 2794 Label true_value, done; |
| 2793 __ testp(rax, rax); | 2795 __ testp(rax, rax); |
| 2794 __ j(condition, &true_value, Label::kNear); | 2796 __ j(condition, &true_value, Label::kNear); |
| 2795 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); | 2797 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); |
| 2796 __ jmp(&done, Label::kNear); | 2798 __ jmp(&done, Label::kNear); |
| 2797 __ bind(&true_value); | 2799 __ bind(&true_value); |
| 2798 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); | 2800 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2865 DCHECK(ToRegister(instr->context()).is(rsi)); | 2867 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 2866 DCHECK(ToRegister(instr->global_object()) | 2868 DCHECK(ToRegister(instr->global_object()) |
| 2867 .is(LoadDescriptor::ReceiverRegister())); | 2869 .is(LoadDescriptor::ReceiverRegister())); |
| 2868 DCHECK(ToRegister(instr->result()).is(rax)); | 2870 DCHECK(ToRegister(instr->result()).is(rax)); |
| 2869 | 2871 |
| 2870 __ Move(LoadDescriptor::NameRegister(), instr->name()); | 2872 __ Move(LoadDescriptor::NameRegister(), instr->name()); |
| 2871 if (FLAG_vector_ics) { | 2873 if (FLAG_vector_ics) { |
| 2872 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); | 2874 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); |
| 2873 } | 2875 } |
| 2874 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; | 2876 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; |
| 2875 Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); | 2877 Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code(); |
| 2876 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2878 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2877 } | 2879 } |
| 2878 | 2880 |
| 2879 | 2881 |
| 2880 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { | 2882 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { |
| 2881 Register value = ToRegister(instr->value()); | 2883 Register value = ToRegister(instr->value()); |
| 2882 Handle<Cell> cell_handle = instr->hydrogen()->cell().handle(); | 2884 Handle<Cell> cell_handle = instr->hydrogen()->cell().handle(); |
| 2883 | 2885 |
| 2884 // If the cell we are storing to contains the hole it could have | 2886 // If the cell we are storing to contains the hole it could have |
| 2885 // been deleted from the property dictionary. In that case, we need | 2887 // been deleted from the property dictionary. In that case, we need |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3007 | 3009 |
| 3008 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3010 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 3009 DCHECK(ToRegister(instr->context()).is(rsi)); | 3011 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 3010 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3012 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3011 DCHECK(ToRegister(instr->result()).is(rax)); | 3013 DCHECK(ToRegister(instr->result()).is(rax)); |
| 3012 | 3014 |
| 3013 __ Move(LoadDescriptor::NameRegister(), instr->name()); | 3015 __ Move(LoadDescriptor::NameRegister(), instr->name()); |
| 3014 if (FLAG_vector_ics) { | 3016 if (FLAG_vector_ics) { |
| 3015 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); | 3017 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); |
| 3016 } | 3018 } |
| 3017 Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); | 3019 Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code(); |
| 3018 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3020 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3019 } | 3021 } |
| 3020 | 3022 |
| 3021 | 3023 |
| 3022 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 3024 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 3023 Register function = ToRegister(instr->function()); | 3025 Register function = ToRegister(instr->function()); |
| 3024 Register result = ToRegister(instr->result()); | 3026 Register result = ToRegister(instr->result()); |
| 3025 | 3027 |
| 3026 // Get the prototype or initial map from the function. | 3028 // Get the prototype or initial map from the function. |
| 3027 __ movp(result, | 3029 __ movp(result, |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3289 | 3291 |
| 3290 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3292 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 3291 DCHECK(ToRegister(instr->context()).is(rsi)); | 3293 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 3292 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3294 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3293 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); | 3295 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); |
| 3294 | 3296 |
| 3295 if (FLAG_vector_ics) { | 3297 if (FLAG_vector_ics) { |
| 3296 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); | 3298 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); |
| 3297 } | 3299 } |
| 3298 | 3300 |
| 3299 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3301 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
| 3300 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3302 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3301 } | 3303 } |
| 3302 | 3304 |
| 3303 | 3305 |
| 3304 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 3306 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
| 3305 Register result = ToRegister(instr->result()); | 3307 Register result = ToRegister(instr->result()); |
| 3306 | 3308 |
| 3307 if (instr->hydrogen()->from_inlined()) { | 3309 if (instr->hydrogen()->from_inlined()) { |
| 3308 __ leap(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize)); | 3310 __ leap(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize)); |
| 3309 } else { | 3311 } else { |
| (...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4476 } | 4478 } |
| 4477 } | 4479 } |
| 4478 | 4480 |
| 4479 | 4481 |
| 4480 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4482 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 4481 DCHECK(ToRegister(instr->context()).is(rsi)); | 4483 DCHECK(ToRegister(instr->context()).is(rsi)); |
| 4482 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); | 4484 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); |
| 4483 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); | 4485 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); |
| 4484 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); | 4486 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); |
| 4485 | 4487 |
| 4486 Handle<Code> ic = instr->strict_mode() == STRICT | 4488 Handle<Code> ic = |
| 4487 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 4489 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code(); |
| 4488 : isolate()->builtins()->KeyedStoreIC_Initialize(); | |
| 4489 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4490 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4490 } | 4491 } |
| 4491 | 4492 |
| 4492 | 4493 |
| 4493 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 4494 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
| 4494 Register object_reg = ToRegister(instr->object()); | 4495 Register object_reg = ToRegister(instr->object()); |
| 4495 | 4496 |
| 4496 Handle<Map> from_map = instr->original_map(); | 4497 Handle<Map> from_map = instr->original_map(); |
| 4497 Handle<Map> to_map = instr->transitioned_map(); | 4498 Handle<Map> to_map = instr->transitioned_map(); |
| 4498 ElementsKind from_kind = instr->from_kind(); | 4499 ElementsKind from_kind = instr->from_kind(); |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5874 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5875 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5875 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5876 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5876 } | 5877 } |
| 5877 | 5878 |
| 5878 | 5879 |
| 5879 #undef __ | 5880 #undef __ |
| 5880 | 5881 |
| 5881 } } // namespace v8::internal | 5882 } } // namespace v8::internal |
| 5882 | 5883 |
| 5883 #endif // V8_TARGET_ARCH_X64 | 5884 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |