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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 5018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5029 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 5029 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
5030 | 5030 |
5031 __ bind(&fast_elements_case); | 5031 __ bind(&fast_elements_case); |
5032 GenerateCase(masm, FAST_ELEMENTS); | 5032 GenerateCase(masm, FAST_ELEMENTS); |
5033 } | 5033 } |
5034 | 5034 |
5035 | 5035 |
5036 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | 5036 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { |
5037 Register context_reg = rsi; | 5037 Register context_reg = rsi; |
5038 Register slot_reg = rbx; | 5038 Register slot_reg = rbx; |
5039 Register name_reg = rcx; | |
5040 Register result_reg = rax; | 5039 Register result_reg = rax; |
5041 Label slow_case; | 5040 Label slow_case; |
5042 | 5041 |
5043 // Go up context chain to the script context. | 5042 // Go up context chain to the script context. |
5044 for (int i = 0; i < depth(); ++i) { | 5043 for (int i = 0; i < depth(); ++i) { |
5045 __ movp(rdi, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 5044 __ movp(rdi, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
5046 context_reg = rdi; | 5045 context_reg = rdi; |
5047 } | 5046 } |
5048 | 5047 |
5049 // Load the PropertyCell value at the specified slot. | 5048 // Load the PropertyCell value at the specified slot. |
5050 __ movp(result_reg, ContextOperand(context_reg, slot_reg)); | 5049 __ movp(result_reg, ContextOperand(context_reg, slot_reg)); |
5051 __ movp(result_reg, FieldOperand(result_reg, PropertyCell::kValueOffset)); | 5050 __ movp(result_reg, FieldOperand(result_reg, PropertyCell::kValueOffset)); |
5052 | 5051 |
5053 // Check that value is not the_hole. | 5052 // Check that value is not the_hole. |
5054 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex); | 5053 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex); |
5055 __ j(equal, &slow_case, Label::kNear); | 5054 __ j(equal, &slow_case, Label::kNear); |
5056 __ Ret(); | 5055 __ Ret(); |
5057 | 5056 |
5058 // Fallback to the runtime. | 5057 // Fallback to the runtime. |
5059 __ bind(&slow_case); | 5058 __ bind(&slow_case); |
5060 __ Integer32ToSmi(slot_reg, slot_reg); | 5059 __ Integer32ToSmi(slot_reg, slot_reg); |
5061 __ PopReturnAddressTo(kScratchRegister); | 5060 __ PopReturnAddressTo(kScratchRegister); |
5062 __ Push(slot_reg); | 5061 __ Push(slot_reg); |
5063 __ Push(name_reg); | |
5064 __ Push(kScratchRegister); | 5062 __ Push(kScratchRegister); |
5065 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 2, 1); | 5063 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1, 1); |
5066 } | 5064 } |
5067 | 5065 |
5068 | 5066 |
5069 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { | 5067 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { |
5070 Register context_reg = rsi; | 5068 Register context_reg = rsi; |
5071 Register slot_reg = rbx; | 5069 Register slot_reg = rbx; |
5072 Register name_reg = rcx; | |
5073 Register value_reg = rax; | 5070 Register value_reg = rax; |
5074 Register cell_reg = r8; | 5071 Register cell_reg = r8; |
5075 Register cell_details_reg = rdx; | 5072 Register cell_details_reg = rdx; |
5076 Register cell_value_reg = r9; | 5073 Register cell_value_reg = r9; |
5077 Label fast_heapobject_case, fast_smi_case, slow_case; | 5074 Label fast_heapobject_case, fast_smi_case, slow_case; |
5078 | 5075 |
5079 if (FLAG_debug_code) { | 5076 if (FLAG_debug_code) { |
5080 __ CompareRoot(value_reg, Heap::kTheHoleValueRootIndex); | 5077 __ CompareRoot(value_reg, Heap::kTheHoleValueRootIndex); |
5081 __ Check(not_equal, kUnexpectedValue); | 5078 __ Check(not_equal, kUnexpectedValue); |
5082 __ AssertName(name_reg); | |
5083 } | 5079 } |
5084 | 5080 |
5085 // Go up context chain to the script context. | 5081 // Go up context chain to the script context. |
5086 for (int i = 0; i < depth(); ++i) { | 5082 for (int i = 0; i < depth(); ++i) { |
5087 __ movp(rdi, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 5083 __ movp(rdi, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
5088 context_reg = rdi; | 5084 context_reg = rdi; |
5089 } | 5085 } |
5090 | 5086 |
5091 // Load the PropertyCell at the specified slot. | 5087 // Load the PropertyCell at the specified slot. |
5092 __ movp(cell_reg, ContextOperand(context_reg, slot_reg)); | 5088 __ movp(cell_reg, ContextOperand(context_reg, slot_reg)); |
5093 | 5089 |
5094 // Load PropertyDetails for the cell (actually only the cell_type and kind). | 5090 // Load PropertyDetails for the cell (actually only the cell_type and kind). |
5095 __ SmiToInteger32(cell_details_reg, | 5091 __ SmiToInteger32(cell_details_reg, |
5096 FieldOperand(cell_reg, PropertyCell::kDetailsOffset)); | 5092 FieldOperand(cell_reg, PropertyCell::kDetailsOffset)); |
5097 __ andl(cell_details_reg, | 5093 __ andl(cell_details_reg, |
5098 Immediate(PropertyDetails::PropertyCellTypeField::kMask | | 5094 Immediate(PropertyDetails::PropertyCellTypeField::kMask | |
5099 PropertyDetails::KindField::kMask)); | 5095 PropertyDetails::KindField::kMask)); |
5100 | 5096 |
5101 | |
5102 // Check if PropertyCell holds mutable data. | 5097 // Check if PropertyCell holds mutable data. |
5103 Label not_mutable_data; | 5098 Label not_mutable_data; |
5104 __ cmpl(cell_details_reg, | 5099 __ cmpl(cell_details_reg, |
5105 Immediate(PropertyDetails::PropertyCellTypeField::encode( | 5100 Immediate(PropertyDetails::PropertyCellTypeField::encode( |
5106 PropertyCellType::kMutable) | | 5101 PropertyCellType::kMutable) | |
5107 PropertyDetails::KindField::encode(kData))); | 5102 PropertyDetails::KindField::encode(kData))); |
5108 __ j(not_equal, ¬_mutable_data); | 5103 __ j(not_equal, ¬_mutable_data); |
5109 __ JumpIfSmi(value_reg, &fast_smi_case); | 5104 __ JumpIfSmi(value_reg, &fast_smi_case); |
5110 __ bind(&fast_heapobject_case); | 5105 __ bind(&fast_heapobject_case); |
5111 __ movp(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); | 5106 __ movp(FieldOperand(cell_reg, PropertyCell::kValueOffset), value_reg); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5170 __ movp(cell_value_map_reg, | 5165 __ movp(cell_value_map_reg, |
5171 FieldOperand(cell_value_reg, HeapObject::kMapOffset)); | 5166 FieldOperand(cell_value_reg, HeapObject::kMapOffset)); |
5172 __ cmpp(cell_value_map_reg, FieldOperand(value_reg, HeapObject::kMapOffset)); | 5167 __ cmpp(cell_value_map_reg, FieldOperand(value_reg, HeapObject::kMapOffset)); |
5173 __ j(equal, &fast_heapobject_case); | 5168 __ j(equal, &fast_heapobject_case); |
5174 | 5169 |
5175 // Fallback to the runtime. | 5170 // Fallback to the runtime. |
5176 __ bind(&slow_case); | 5171 __ bind(&slow_case); |
5177 __ Integer32ToSmi(slot_reg, slot_reg); | 5172 __ Integer32ToSmi(slot_reg, slot_reg); |
5178 __ PopReturnAddressTo(kScratchRegister); | 5173 __ PopReturnAddressTo(kScratchRegister); |
5179 __ Push(slot_reg); | 5174 __ Push(slot_reg); |
5180 __ Push(name_reg); | |
5181 __ Push(value_reg); | 5175 __ Push(value_reg); |
5182 __ Push(kScratchRegister); | 5176 __ Push(kScratchRegister); |
5183 __ TailCallRuntime(is_strict(language_mode()) | 5177 __ TailCallRuntime(is_strict(language_mode()) |
5184 ? Runtime::kStoreGlobalViaContext_Strict | 5178 ? Runtime::kStoreGlobalViaContext_Strict |
5185 : Runtime::kStoreGlobalViaContext_Sloppy, | 5179 : Runtime::kStoreGlobalViaContext_Sloppy, |
5186 3, 1); | 5180 2, 1); |
5187 } | 5181 } |
5188 | 5182 |
5189 | 5183 |
5190 static int Offset(ExternalReference ref0, ExternalReference ref1) { | 5184 static int Offset(ExternalReference ref0, ExternalReference ref1) { |
5191 int64_t offset = (ref0.address() - ref1.address()); | 5185 int64_t offset = (ref0.address() - ref1.address()); |
5192 // Check that fits into int. | 5186 // Check that fits into int. |
5193 DCHECK(static_cast<int>(offset) == offset); | 5187 DCHECK(static_cast<int>(offset) == offset); |
5194 return static_cast<int>(offset); | 5188 return static_cast<int>(offset); |
5195 } | 5189 } |
5196 | 5190 |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5582 kStackSpace, nullptr, return_value_operand, NULL); | 5576 kStackSpace, nullptr, return_value_operand, NULL); |
5583 } | 5577 } |
5584 | 5578 |
5585 | 5579 |
5586 #undef __ | 5580 #undef __ |
5587 | 5581 |
5588 } // namespace internal | 5582 } // namespace internal |
5589 } // namespace v8 | 5583 } // namespace v8 |
5590 | 5584 |
5591 #endif // V8_TARGET_ARCH_X64 | 5585 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |