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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 2974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2985 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2985 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2986 } | 2986 } |
2987 | 2987 |
2988 | 2988 |
2989 void FullCodeGenerator::EmitLoadSuperConstructor() { | 2989 void FullCodeGenerator::EmitLoadSuperConstructor() { |
2990 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2990 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
2991 __ CallRuntime(Runtime::kGetPrototype, 1); | 2991 __ CallRuntime(Runtime::kGetPrototype, 1); |
2992 } | 2992 } |
2993 | 2993 |
2994 | 2994 |
| 2995 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 2996 SuperReference* super_ref) { |
| 2997 Variable* this_var = super_ref->this_var()->var(); |
| 2998 GetVar(ecx, this_var); |
| 2999 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
| 3000 Label uninitialized_this; |
| 3001 __ j(equal, &uninitialized_this); |
| 3002 __ push(Immediate(this_var->name())); |
| 3003 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 3004 __ bind(&uninitialized_this); |
| 3005 |
| 3006 EmitVariableAssignment(this_var, Token::INIT_CONST); |
| 3007 } |
| 3008 |
| 3009 |
2995 void FullCodeGenerator::VisitCall(Call* expr) { | 3010 void FullCodeGenerator::VisitCall(Call* expr) { |
2996 #ifdef DEBUG | 3011 #ifdef DEBUG |
2997 // We want to verify that RecordJSReturnSite gets called on all paths | 3012 // We want to verify that RecordJSReturnSite gets called on all paths |
2998 // through this function. Avoid early returns. | 3013 // through this function. Avoid early returns. |
2999 expr->return_is_recorded_ = false; | 3014 expr->return_is_recorded_ = false; |
3000 #endif | 3015 #endif |
3001 | 3016 |
3002 Comment cmnt(masm_, "[ Call"); | 3017 Comment cmnt(masm_, "[ Call"); |
3003 Expression* callee = expr->expression(); | 3018 Expression* callee = expr->expression(); |
3004 Call::CallType call_type = expr->GetCallType(isolate()); | 3019 Call::CallType call_type = expr->GetCallType(isolate()); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3199 __ LoadHeapObject(ebx, FeedbackVector()); | 3214 __ LoadHeapObject(ebx, FeedbackVector()); |
3200 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3215 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
3201 | 3216 |
3202 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3217 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3203 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3218 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3204 | 3219 |
3205 __ Drop(1); | 3220 __ Drop(1); |
3206 | 3221 |
3207 RecordJSReturnSite(expr); | 3222 RecordJSReturnSite(expr); |
3208 | 3223 |
3209 SuperReference* super_ref = expr->expression()->AsSuperReference(); | 3224 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); |
3210 Variable* this_var = super_ref->this_var()->var(); | |
3211 GetVar(ecx, this_var); | |
3212 __ cmp(ecx, isolate()->factory()->the_hole_value()); | |
3213 Label uninitialized_this; | |
3214 __ j(equal, &uninitialized_this); | |
3215 __ push(Immediate(this_var->name())); | |
3216 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3217 __ bind(&uninitialized_this); | |
3218 | |
3219 EmitVariableAssignment(this_var, Token::INIT_CONST); | |
3220 context()->Plug(eax); | 3225 context()->Plug(eax); |
3221 } | 3226 } |
3222 | 3227 |
3223 | 3228 |
3224 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3229 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3225 ZoneList<Expression*>* args = expr->arguments(); | 3230 ZoneList<Expression*>* args = expr->arguments(); |
3226 DCHECK(args->length() == 1); | 3231 DCHECK(args->length() == 1); |
3227 | 3232 |
3228 VisitForAccumulatorValue(args->at(0)); | 3233 VisitForAccumulatorValue(args->at(0)); |
3229 | 3234 |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4510 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { | 4515 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { |
4511 DCHECK(expr->arguments()->length() == 0); | 4516 DCHECK(expr->arguments()->length() == 0); |
4512 ExternalReference debug_is_active = | 4517 ExternalReference debug_is_active = |
4513 ExternalReference::debug_is_active_address(isolate()); | 4518 ExternalReference::debug_is_active_address(isolate()); |
4514 __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); | 4519 __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); |
4515 __ SmiTag(eax); | 4520 __ SmiTag(eax); |
4516 context()->Plug(eax); | 4521 context()->Plug(eax); |
4517 } | 4522 } |
4518 | 4523 |
4519 | 4524 |
| 4525 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
| 4526 // Assert: expr == CallRuntime("ReflectConstruct") |
| 4527 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); |
| 4528 ZoneList<Expression*>* args = call->arguments(); |
| 4529 DCHECK_EQ(3, args->length()); |
| 4530 |
| 4531 SuperReference* super_reference = args->at(0)->AsSuperReference(); |
| 4532 |
| 4533 // Load ReflectConstruct function |
| 4534 EmitLoadJSRuntimeFunction(call); |
| 4535 |
| 4536 // Push the target function under the receiver |
| 4537 __ push(Operand(esp, 0)); |
| 4538 __ mov(Operand(esp, kPointerSize), eax); |
| 4539 |
| 4540 // Push super |
| 4541 EmitLoadSuperConstructor(); |
| 4542 __ Push(result_register()); |
| 4543 |
| 4544 // Push arguments array |
| 4545 VisitForStackValue(args->at(1)); |
| 4546 |
| 4547 // Push NewTarget |
| 4548 DCHECK(args->at(2)->IsVariableProxy()); |
| 4549 VisitForStackValue(args->at(2)); |
| 4550 |
| 4551 EmitCallJSRuntimeFunction(call); |
| 4552 |
| 4553 // Restore context register. |
| 4554 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 4555 context()->DropAndPlug(1, eax); |
| 4556 |
| 4557 EmitInitializeThisAfterSuper(super_reference); |
| 4558 } |
| 4559 |
| 4560 |
| 4561 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4562 // Push the builtins object as receiver. |
| 4563 __ mov(eax, GlobalObjectOperand()); |
| 4564 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
| 4565 |
| 4566 // Load the function from the receiver. |
| 4567 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 4568 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); |
| 4569 if (FLAG_vector_ics) { |
| 4570 __ mov(VectorLoadICDescriptor::SlotRegister(), |
| 4571 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
| 4572 CallLoadIC(NOT_CONTEXTUAL); |
| 4573 } else { |
| 4574 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4575 } |
| 4576 } |
| 4577 |
| 4578 |
| 4579 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 4580 ZoneList<Expression*>* args = expr->arguments(); |
| 4581 int arg_count = args->length(); |
| 4582 |
| 4583 // Record source position of the IC call. |
| 4584 SetSourcePosition(expr->position()); |
| 4585 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4586 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 4587 __ CallStub(&stub); |
| 4588 } |
| 4589 |
| 4590 |
4520 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4591 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4521 ZoneList<Expression*>* args = expr->arguments(); | 4592 ZoneList<Expression*>* args = expr->arguments(); |
4522 int arg_count = args->length(); | 4593 int arg_count = args->length(); |
4523 | 4594 |
4524 if (expr->is_jsruntime()) { | 4595 if (expr->is_jsruntime()) { |
4525 Comment cmnt(masm_, "[ CallRuntime"); | 4596 Comment cmnt(masm_, "[ CallRuntime"); |
4526 // Push the builtins object as receiver. | 4597 EmitLoadJSRuntimeFunction(expr); |
4527 __ mov(eax, GlobalObjectOperand()); | |
4528 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | |
4529 | |
4530 // Load the function from the receiver. | |
4531 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | |
4532 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); | |
4533 if (FLAG_vector_ics) { | |
4534 __ mov(VectorLoadICDescriptor::SlotRegister(), | |
4535 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | |
4536 CallLoadIC(NOT_CONTEXTUAL); | |
4537 } else { | |
4538 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | |
4539 } | |
4540 | 4598 |
4541 // Push the target function under the receiver. | 4599 // Push the target function under the receiver. |
4542 __ push(Operand(esp, 0)); | 4600 __ push(Operand(esp, 0)); |
4543 __ mov(Operand(esp, kPointerSize), eax); | 4601 __ mov(Operand(esp, kPointerSize), eax); |
4544 | 4602 |
4545 // Push the arguments ("left-to-right"). | 4603 // Push the arguments ("left-to-right"). |
4546 for (int i = 0; i < arg_count; i++) { | 4604 for (int i = 0; i < arg_count; i++) { |
4547 VisitForStackValue(args->at(i)); | 4605 VisitForStackValue(args->at(i)); |
4548 } | 4606 } |
4549 | 4607 |
4550 // Record source position of the IC call. | 4608 EmitCallJSRuntimeFunction(expr); |
4551 SetSourcePosition(expr->position()); | 4609 |
4552 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
4553 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | |
4554 __ CallStub(&stub); | |
4555 // Restore context register. | 4610 // Restore context register. |
4556 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4611 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4557 context()->DropAndPlug(1, eax); | 4612 context()->DropAndPlug(1, eax); |
4558 | 4613 |
4559 } else { | 4614 } else { |
4560 const Runtime::Function* function = expr->function(); | 4615 const Runtime::Function* function = expr->function(); |
4561 switch (function->function_id) { | 4616 switch (function->function_id) { |
4562 #define CALL_INTRINSIC_GENERATOR(Name) \ | 4617 #define CALL_INTRINSIC_GENERATOR(Name) \ |
4563 case Runtime::kInline##Name: { \ | 4618 case Runtime::kInline##Name: { \ |
4564 Comment cmnt(masm_, "[ Inline" #Name); \ | 4619 Comment cmnt(masm_, "[ Inline" #Name); \ |
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5327 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5382 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5328 Assembler::target_address_at(call_target_address, | 5383 Assembler::target_address_at(call_target_address, |
5329 unoptimized_code)); | 5384 unoptimized_code)); |
5330 return OSR_AFTER_STACK_CHECK; | 5385 return OSR_AFTER_STACK_CHECK; |
5331 } | 5386 } |
5332 | 5387 |
5333 | 5388 |
5334 } } // namespace v8::internal | 5389 } } // namespace v8::internal |
5335 | 5390 |
5336 #endif // V8_TARGET_ARCH_X87 | 5391 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |