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 |