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 #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/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3001 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 3001 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
3002 } | 3002 } |
3003 | 3003 |
3004 | 3004 |
3005 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3005 void FullCodeGenerator::EmitLoadSuperConstructor() { |
3006 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 3006 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
3007 __ CallRuntime(Runtime::kGetPrototype, 1); | 3007 __ CallRuntime(Runtime::kGetPrototype, 1); |
3008 } | 3008 } |
3009 | 3009 |
3010 | 3010 |
| 3011 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 3012 SuperReference* super_ref) { |
| 3013 Variable* this_var = super_ref->this_var()->var(); |
| 3014 GetVar(rcx, this_var); |
| 3015 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); |
| 3016 Label uninitialized_this; |
| 3017 __ j(equal, &uninitialized_this); |
| 3018 __ Push(this_var->name()); |
| 3019 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 3020 __ bind(&uninitialized_this); |
| 3021 |
| 3022 EmitVariableAssignment(this_var, Token::INIT_CONST); |
| 3023 } |
| 3024 |
| 3025 |
3011 void FullCodeGenerator::VisitCall(Call* expr) { | 3026 void FullCodeGenerator::VisitCall(Call* expr) { |
3012 #ifdef DEBUG | 3027 #ifdef DEBUG |
3013 // We want to verify that RecordJSReturnSite gets called on all paths | 3028 // We want to verify that RecordJSReturnSite gets called on all paths |
3014 // through this function. Avoid early returns. | 3029 // through this function. Avoid early returns. |
3015 expr->return_is_recorded_ = false; | 3030 expr->return_is_recorded_ = false; |
3016 #endif | 3031 #endif |
3017 | 3032 |
3018 Comment cmnt(masm_, "[ Call"); | 3033 Comment cmnt(masm_, "[ Call"); |
3019 Expression* callee = expr->expression(); | 3034 Expression* callee = expr->expression(); |
3020 Call::CallType call_type = expr->GetCallType(isolate()); | 3035 Call::CallType call_type = expr->GetCallType(isolate()); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3215 __ Move(rbx, FeedbackVector()); | 3230 __ Move(rbx, FeedbackVector()); |
3216 __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); | 3231 __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); |
3217 | 3232 |
3218 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3233 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3219 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3234 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3220 | 3235 |
3221 __ Drop(1); | 3236 __ Drop(1); |
3222 | 3237 |
3223 RecordJSReturnSite(expr); | 3238 RecordJSReturnSite(expr); |
3224 | 3239 |
3225 SuperReference* super_ref = expr->expression()->AsSuperReference(); | 3240 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); |
3226 Variable* this_var = super_ref->this_var()->var(); | |
3227 GetVar(rcx, this_var); | |
3228 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); | |
3229 Label uninitialized_this; | |
3230 __ j(equal, &uninitialized_this); | |
3231 __ Push(this_var->name()); | |
3232 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3233 __ bind(&uninitialized_this); | |
3234 | |
3235 EmitVariableAssignment(this_var, Token::INIT_CONST); | |
3236 context()->Plug(rax); | 3241 context()->Plug(rax); |
3237 } | 3242 } |
3238 | 3243 |
3239 | 3244 |
3240 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3245 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3241 ZoneList<Expression*>* args = expr->arguments(); | 3246 ZoneList<Expression*>* args = expr->arguments(); |
3242 DCHECK(args->length() == 1); | 3247 DCHECK(args->length() == 1); |
3243 | 3248 |
3244 VisitForAccumulatorValue(args->at(0)); | 3249 VisitForAccumulatorValue(args->at(0)); |
3245 | 3250 |
(...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4546 DCHECK(expr->arguments()->length() == 0); | 4551 DCHECK(expr->arguments()->length() == 0); |
4547 ExternalReference debug_is_active = | 4552 ExternalReference debug_is_active = |
4548 ExternalReference::debug_is_active_address(isolate()); | 4553 ExternalReference::debug_is_active_address(isolate()); |
4549 __ Move(kScratchRegister, debug_is_active); | 4554 __ Move(kScratchRegister, debug_is_active); |
4550 __ movzxbp(rax, Operand(kScratchRegister, 0)); | 4555 __ movzxbp(rax, Operand(kScratchRegister, 0)); |
4551 __ Integer32ToSmi(rax, rax); | 4556 __ Integer32ToSmi(rax, rax); |
4552 context()->Plug(rax); | 4557 context()->Plug(rax); |
4553 } | 4558 } |
4554 | 4559 |
4555 | 4560 |
| 4561 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
| 4562 // Assert: expr === CallRuntime("ReflectConstruct") |
| 4563 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); |
| 4564 ZoneList<Expression*>* args = call->arguments(); |
| 4565 DCHECK_EQ(3, args->length()); |
| 4566 |
| 4567 SuperReference* super_reference = args->at(0)->AsSuperReference(); |
| 4568 |
| 4569 // Load ReflectConstruct function |
| 4570 EmitLoadJSRuntimeFunction(call); |
| 4571 |
| 4572 // Push the target function under the receiver. |
| 4573 __ Push(Operand(rsp, 0)); |
| 4574 __ movp(Operand(rsp, kPointerSize), rax); |
| 4575 |
| 4576 // Push super |
| 4577 EmitLoadSuperConstructor(); |
| 4578 __ Push(result_register()); |
| 4579 |
| 4580 // Push arguments array |
| 4581 VisitForStackValue(args->at(1)); |
| 4582 |
| 4583 // Push NewTarget |
| 4584 DCHECK(args->at(2)->IsVariableProxy()); |
| 4585 VisitForStackValue(args->at(2)); |
| 4586 |
| 4587 EmitCallJSRuntimeFunction(call); |
| 4588 |
| 4589 // Restore context register. |
| 4590 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 4591 context()->DropAndPlug(1, rax); |
| 4592 |
| 4593 EmitInitializeThisAfterSuper(super_reference); |
| 4594 } |
| 4595 |
| 4596 |
| 4597 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4598 // Push the builtins object as receiver. |
| 4599 __ movp(rax, GlobalObjectOperand()); |
| 4600 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
| 4601 |
| 4602 // Load the function from the receiver. |
| 4603 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 4604 __ Move(LoadDescriptor::NameRegister(), expr->name()); |
| 4605 if (FLAG_vector_ics) { |
| 4606 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 4607 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); |
| 4608 CallLoadIC(NOT_CONTEXTUAL); |
| 4609 } else { |
| 4610 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4611 } |
| 4612 } |
| 4613 |
| 4614 |
| 4615 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 4616 ZoneList<Expression*>* args = expr->arguments(); |
| 4617 int arg_count = args->length(); |
| 4618 |
| 4619 // Record source position of the IC call. |
| 4620 SetSourcePosition(expr->position()); |
| 4621 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4622 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
| 4623 __ CallStub(&stub); |
| 4624 } |
| 4625 |
| 4626 |
4556 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4627 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4557 ZoneList<Expression*>* args = expr->arguments(); | 4628 ZoneList<Expression*>* args = expr->arguments(); |
4558 int arg_count = args->length(); | 4629 int arg_count = args->length(); |
4559 | 4630 |
4560 if (expr->is_jsruntime()) { | 4631 if (expr->is_jsruntime()) { |
4561 Comment cmnt(masm_, "[ CallRuntime"); | 4632 Comment cmnt(masm_, "[ CallRuntime"); |
4562 // Push the builtins object as receiver. | |
4563 __ movp(rax, GlobalObjectOperand()); | |
4564 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | |
4565 | 4633 |
4566 // Load the function from the receiver. | 4634 EmitLoadJSRuntimeFunction(expr); |
4567 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | |
4568 __ Move(LoadDescriptor::NameRegister(), expr->name()); | |
4569 if (FLAG_vector_ics) { | |
4570 __ Move(VectorLoadICDescriptor::SlotRegister(), | |
4571 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); | |
4572 CallLoadIC(NOT_CONTEXTUAL); | |
4573 } else { | |
4574 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | |
4575 } | |
4576 | 4635 |
4577 // Push the target function under the receiver. | 4636 // Push the target function under the receiver. |
4578 __ Push(Operand(rsp, 0)); | 4637 __ Push(Operand(rsp, 0)); |
4579 __ movp(Operand(rsp, kPointerSize), rax); | 4638 __ movp(Operand(rsp, kPointerSize), rax); |
4580 | 4639 |
4581 // Push the arguments ("left-to-right"). | 4640 // Push the arguments ("left-to-right"). |
4582 for (int i = 0; i < arg_count; i++) { | 4641 for (int i = 0; i < arg_count; i++) { |
4583 VisitForStackValue(args->at(i)); | 4642 VisitForStackValue(args->at(i)); |
4584 } | 4643 } |
4585 | 4644 |
4586 // Record source position of the IC call. | 4645 EmitCallJSRuntimeFunction(expr); |
4587 SetSourcePosition(expr->position()); | |
4588 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
4589 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | |
4590 __ CallStub(&stub); | |
4591 | 4646 |
4592 // Restore context register. | 4647 // Restore context register. |
4593 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4648 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
4594 context()->DropAndPlug(1, rax); | 4649 context()->DropAndPlug(1, rax); |
4595 | 4650 |
4596 } else { | 4651 } else { |
4597 const Runtime::Function* function = expr->function(); | 4652 const Runtime::Function* function = expr->function(); |
4598 switch (function->function_id) { | 4653 switch (function->function_id) { |
4599 #define CALL_INTRINSIC_GENERATOR(Name) \ | 4654 #define CALL_INTRINSIC_GENERATOR(Name) \ |
4600 case Runtime::kInline##Name: { \ | 4655 case Runtime::kInline##Name: { \ |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5362 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5417 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5363 Assembler::target_address_at(call_target_address, | 5418 Assembler::target_address_at(call_target_address, |
5364 unoptimized_code)); | 5419 unoptimized_code)); |
5365 return OSR_AFTER_STACK_CHECK; | 5420 return OSR_AFTER_STACK_CHECK; |
5366 } | 5421 } |
5367 | 5422 |
5368 | 5423 |
5369 } } // namespace v8::internal | 5424 } } // namespace v8::internal |
5370 | 5425 |
5371 #endif // V8_TARGET_ARCH_X64 | 5426 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |