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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/crankshaft/x64/lithium-codegen-x64.h" | 7 #include "src/crankshaft/x64/lithium-codegen-x64.h" |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 // Possibly allocate a local context. | 177 // Possibly allocate a local context. |
178 if (info_->num_heap_slots() > 0) { | 178 if (info_->num_heap_slots() > 0) { |
179 Comment(";;; Allocate local context"); | 179 Comment(";;; Allocate local context"); |
180 bool need_write_barrier = true; | 180 bool need_write_barrier = true; |
181 // Argument to NewContext is the function, which is still in rdi. | 181 // Argument to NewContext is the function, which is still in rdi. |
182 int slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 182 int slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
183 Safepoint::DeoptMode deopt_mode = Safepoint::kNoLazyDeopt; | 183 Safepoint::DeoptMode deopt_mode = Safepoint::kNoLazyDeopt; |
184 if (info()->scope()->is_script_scope()) { | 184 if (info()->scope()->is_script_scope()) { |
185 __ Push(rdi); | 185 __ Push(rdi); |
186 __ Push(info()->scope()->GetScopeInfo(info()->isolate())); | 186 __ Push(info()->scope()->GetScopeInfo(info()->isolate())); |
187 __ CallRuntime(Runtime::kNewScriptContext, 2); | 187 __ CallRuntime(Runtime::kNewScriptContext); |
188 deopt_mode = Safepoint::kLazyDeopt; | 188 deopt_mode = Safepoint::kLazyDeopt; |
189 } else if (slots <= FastNewContextStub::kMaximumSlots) { | 189 } else if (slots <= FastNewContextStub::kMaximumSlots) { |
190 FastNewContextStub stub(isolate(), slots); | 190 FastNewContextStub stub(isolate(), slots); |
191 __ CallStub(&stub); | 191 __ CallStub(&stub); |
192 // Result of FastNewContextStub is always in new space. | 192 // Result of FastNewContextStub is always in new space. |
193 need_write_barrier = false; | 193 need_write_barrier = false; |
194 } else { | 194 } else { |
195 __ Push(rdi); | 195 __ Push(rdi); |
196 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 196 __ CallRuntime(Runtime::kNewFunctionContext); |
197 } | 197 } |
198 RecordSafepoint(deopt_mode); | 198 RecordSafepoint(deopt_mode); |
199 | 199 |
200 // Context is returned in rax. It replaces the context passed to us. | 200 // Context is returned in rax. It replaces the context passed to us. |
201 // It's saved in the stack and kept live in rsi. | 201 // It's saved in the stack and kept live in rsi. |
202 __ movp(rsi, rax); | 202 __ movp(rsi, rax); |
203 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); | 203 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); |
204 | 204 |
205 // Copy any necessary parameters into the context. | 205 // Copy any necessary parameters into the context. |
206 int num_parameters = scope()->num_parameters(); | 206 int num_parameters = scope()->num_parameters(); |
(...skipping 2417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2624 | 2624 |
2625 | 2625 |
2626 void LCodeGen::DoReturn(LReturn* instr) { | 2626 void LCodeGen::DoReturn(LReturn* instr) { |
2627 if (FLAG_trace && info()->IsOptimizing()) { | 2627 if (FLAG_trace && info()->IsOptimizing()) { |
2628 // Preserve the return value on the stack and rely on the runtime call | 2628 // Preserve the return value on the stack and rely on the runtime call |
2629 // to return the value in the same register. We're leaving the code | 2629 // to return the value in the same register. We're leaving the code |
2630 // managed by the register allocator and tearing down the frame, it's | 2630 // managed by the register allocator and tearing down the frame, it's |
2631 // safe to write to the context register. | 2631 // safe to write to the context register. |
2632 __ Push(rax); | 2632 __ Push(rax); |
2633 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2633 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2634 __ CallRuntime(Runtime::kTraceExit, 1); | 2634 __ CallRuntime(Runtime::kTraceExit); |
2635 } | 2635 } |
2636 if (info()->saves_caller_doubles()) { | 2636 if (info()->saves_caller_doubles()) { |
2637 RestoreCallerDoubles(); | 2637 RestoreCallerDoubles(); |
2638 } | 2638 } |
2639 if (NeedsEagerFrame()) { | 2639 if (NeedsEagerFrame()) { |
2640 __ movp(rsp, rbp); | 2640 __ movp(rsp, rbp); |
2641 __ popq(rbp); | 2641 __ popq(rbp); |
2642 } | 2642 } |
2643 if (instr->has_constant_parameter_count()) { | 2643 if (instr->has_constant_parameter_count()) { |
2644 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize, | 2644 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize, |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3278 // If there is no frame, the context must be in rsi. | 3278 // If there is no frame, the context must be in rsi. |
3279 DCHECK(result.is(rsi)); | 3279 DCHECK(result.is(rsi)); |
3280 } | 3280 } |
3281 } | 3281 } |
3282 | 3282 |
3283 | 3283 |
3284 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3284 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
3285 DCHECK(ToRegister(instr->context()).is(rsi)); | 3285 DCHECK(ToRegister(instr->context()).is(rsi)); |
3286 __ Push(instr->hydrogen()->pairs()); | 3286 __ Push(instr->hydrogen()->pairs()); |
3287 __ Push(Smi::FromInt(instr->hydrogen()->flags())); | 3287 __ Push(Smi::FromInt(instr->hydrogen()->flags())); |
3288 CallRuntime(Runtime::kDeclareGlobals, 2, instr); | 3288 CallRuntime(Runtime::kDeclareGlobals, instr); |
3289 } | 3289 } |
3290 | 3290 |
3291 | 3291 |
3292 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3292 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
3293 int formal_parameter_count, int arity, | 3293 int formal_parameter_count, int arity, |
3294 LInstruction* instr) { | 3294 LInstruction* instr) { |
3295 bool dont_adapt_arguments = | 3295 bool dont_adapt_arguments = |
3296 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3296 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3297 bool can_invoke_directly = | 3297 bool can_invoke_directly = |
3298 dont_adapt_arguments || formal_parameter_count == arity; | 3298 dont_adapt_arguments || formal_parameter_count == arity; |
(...skipping 2269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5568 Register null_value = rdi; | 5568 Register null_value = rdi; |
5569 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 5569 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
5570 __ CheckEnumCache(null_value, &call_runtime); | 5570 __ CheckEnumCache(null_value, &call_runtime); |
5571 | 5571 |
5572 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); | 5572 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); |
5573 __ jmp(&use_cache, Label::kNear); | 5573 __ jmp(&use_cache, Label::kNear); |
5574 | 5574 |
5575 // Get the set of properties to enumerate. | 5575 // Get the set of properties to enumerate. |
5576 __ bind(&call_runtime); | 5576 __ bind(&call_runtime); |
5577 __ Push(rax); | 5577 __ Push(rax); |
5578 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); | 5578 CallRuntime(Runtime::kGetPropertyNamesFast, instr); |
5579 | 5579 |
5580 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 5580 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |
5581 Heap::kMetaMapRootIndex); | 5581 Heap::kMetaMapRootIndex); |
5582 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); | 5582 DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); |
5583 __ bind(&use_cache); | 5583 __ bind(&use_cache); |
5584 } | 5584 } |
5585 | 5585 |
5586 | 5586 |
5587 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { | 5587 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { |
5588 Register map = ToRegister(instr->map()); | 5588 Register map = ToRegister(instr->map()); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5688 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { | 5688 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { |
5689 Register context = ToRegister(instr->context()); | 5689 Register context = ToRegister(instr->context()); |
5690 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), context); | 5690 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), context); |
5691 } | 5691 } |
5692 | 5692 |
5693 | 5693 |
5694 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) { | 5694 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) { |
5695 Handle<ScopeInfo> scope_info = instr->scope_info(); | 5695 Handle<ScopeInfo> scope_info = instr->scope_info(); |
5696 __ Push(scope_info); | 5696 __ Push(scope_info); |
5697 __ Push(ToRegister(instr->function())); | 5697 __ Push(ToRegister(instr->function())); |
5698 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5698 CallRuntime(Runtime::kPushBlockContext, instr); |
5699 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5699 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5700 } | 5700 } |
5701 | 5701 |
5702 | 5702 |
5703 #undef __ | 5703 #undef __ |
5704 | 5704 |
5705 } // namespace internal | 5705 } // namespace internal |
5706 } // namespace v8 | 5706 } // namespace v8 |
5707 | 5707 |
5708 #endif // V8_TARGET_ARCH_X64 | 5708 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |