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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 | 418 |
419 SetReturnPosition(literal()); | 419 SetReturnPosition(literal()); |
420 __ leave(); | 420 __ leave(); |
421 | 421 |
422 int arg_count = info_->scope()->num_parameters() + 1; | 422 int arg_count = info_->scope()->num_parameters() + 1; |
423 int arguments_bytes = arg_count * kPointerSize; | 423 int arguments_bytes = arg_count * kPointerSize; |
424 __ Ret(arguments_bytes, rcx); | 424 __ Ret(arguments_bytes, rcx); |
425 } | 425 } |
426 } | 426 } |
427 | 427 |
| 428 void FullCodeGenerator::RestoreContext() { |
| 429 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 430 } |
428 | 431 |
429 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 432 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
430 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 433 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
431 MemOperand operand = codegen()->VarOperand(var, result_register()); | 434 MemOperand operand = codegen()->VarOperand(var, result_register()); |
432 codegen()->PushOperand(operand); | 435 codegen()->PushOperand(operand); |
433 } | 436 } |
434 | 437 |
435 | 438 |
436 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 439 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
437 } | 440 } |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 __ Push(constant_properties); | 1369 __ Push(constant_properties); |
1367 __ Push(Smi::FromInt(flags)); | 1370 __ Push(Smi::FromInt(flags)); |
1368 __ CallRuntime(Runtime::kCreateObjectLiteral); | 1371 __ CallRuntime(Runtime::kCreateObjectLiteral); |
1369 } else { | 1372 } else { |
1370 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1373 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1371 __ Move(rbx, Smi::FromInt(expr->literal_index())); | 1374 __ Move(rbx, Smi::FromInt(expr->literal_index())); |
1372 __ Move(rcx, constant_properties); | 1375 __ Move(rcx, constant_properties); |
1373 __ Move(rdx, Smi::FromInt(flags)); | 1376 __ Move(rdx, Smi::FromInt(flags)); |
1374 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1377 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
1375 __ CallStub(&stub); | 1378 __ CallStub(&stub); |
1376 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1379 RestoreContext(); |
1377 } | 1380 } |
1378 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1381 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1379 | 1382 |
1380 // If result_saved is true the result is on top of the stack. If | 1383 // If result_saved is true the result is on top of the stack. If |
1381 // result_saved is false the result is in rax. | 1384 // result_saved is false the result is in rax. |
1382 bool result_saved = false; | 1385 bool result_saved = false; |
1383 | 1386 |
1384 AccessorTable accessor_table(zone()); | 1387 AccessorTable accessor_table(zone()); |
1385 int property_index = 0; | 1388 int property_index = 0; |
1386 for (; property_index < expr->properties()->length(); property_index++) { | 1389 for (; property_index < expr->properties()->length(); property_index++) { |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 Smi::FromInt(continuation.pos())); | 1802 Smi::FromInt(continuation.pos())); |
1800 __ movp(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); | 1803 __ movp(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); |
1801 __ movp(rcx, rsi); | 1804 __ movp(rcx, rsi); |
1802 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, | 1805 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, |
1803 kDontSaveFPRegs); | 1806 kDontSaveFPRegs); |
1804 __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); | 1807 __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); |
1805 __ cmpp(rsp, rbx); | 1808 __ cmpp(rsp, rbx); |
1806 __ j(equal, &post_runtime); | 1809 __ j(equal, &post_runtime); |
1807 __ Push(rax); // generator object | 1810 __ Push(rax); // generator object |
1808 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1811 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1809 __ movp(context_register(), | 1812 RestoreContext(); |
1810 Operand(rbp, StandardFrameConstants::kContextOffset)); | |
1811 __ bind(&post_runtime); | 1813 __ bind(&post_runtime); |
1812 | 1814 |
1813 PopOperand(result_register()); | 1815 PopOperand(result_register()); |
1814 EmitReturnSequence(); | 1816 EmitReturnSequence(); |
1815 | 1817 |
1816 __ bind(&resume); | 1818 __ bind(&resume); |
1817 context()->Plug(result_register()); | 1819 context()->Plug(result_register()); |
1818 } | 1820 } |
1819 | 1821 |
1820 void FullCodeGenerator::PushOperand(MemOperand operand) { | 1822 void FullCodeGenerator::PushOperand(MemOperand operand) { |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2406 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2408 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2407 .code(); | 2409 .code(); |
2408 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); | 2410 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); |
2409 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2411 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2410 // Don't assign a type feedback id to the IC, since type feedback is provided | 2412 // Don't assign a type feedback id to the IC, since type feedback is provided |
2411 // by the vector above. | 2413 // by the vector above. |
2412 CallIC(ic); | 2414 CallIC(ic); |
2413 OperandStackDepthDecrement(arg_count + 1); | 2415 OperandStackDepthDecrement(arg_count + 1); |
2414 | 2416 |
2415 RecordJSReturnSite(expr); | 2417 RecordJSReturnSite(expr); |
2416 | 2418 RestoreContext(); |
2417 // Restore context register. | |
2418 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2419 // Discard the function left on TOS. | 2419 // Discard the function left on TOS. |
2420 context()->DropAndPlug(1, rax); | 2420 context()->DropAndPlug(1, rax); |
2421 } | 2421 } |
2422 | 2422 |
2423 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { | 2423 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { |
2424 int arg_count = expr->arguments()->length(); | 2424 int arg_count = expr->arguments()->length(); |
2425 // Push copy of the first argument or undefined if it doesn't exist. | 2425 // Push copy of the first argument or undefined if it doesn't exist. |
2426 if (arg_count > 0) { | 2426 if (arg_count > 0) { |
2427 __ Push(Operand(rsp, arg_count * kPointerSize)); | 2427 __ Push(Operand(rsp, arg_count * kPointerSize)); |
2428 } else { | 2428 } else { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2511 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2512 | 2512 |
2513 SetCallPosition(expr); | 2513 SetCallPosition(expr); |
2514 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2514 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2515 __ Set(rax, arg_count); | 2515 __ Set(rax, arg_count); |
2516 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2516 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2517 expr->tail_call_mode()), | 2517 expr->tail_call_mode()), |
2518 RelocInfo::CODE_TARGET); | 2518 RelocInfo::CODE_TARGET); |
2519 OperandStackDepthDecrement(arg_count + 1); | 2519 OperandStackDepthDecrement(arg_count + 1); |
2520 RecordJSReturnSite(expr); | 2520 RecordJSReturnSite(expr); |
2521 // Restore context register. | 2521 RestoreContext(); |
2522 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2523 context()->DropAndPlug(1, rax); | 2522 context()->DropAndPlug(1, rax); |
2524 } | 2523 } |
2525 | 2524 |
2526 | 2525 |
2527 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2526 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2528 Comment cmnt(masm_, "[ CallNew"); | 2527 Comment cmnt(masm_, "[ CallNew"); |
2529 // According to ECMA-262, section 11.2.2, page 44, the function | 2528 // According to ECMA-262, section 11.2.2, page 44, the function |
2530 // expression in new calls must be evaluated before the | 2529 // expression in new calls must be evaluated before the |
2531 // arguments. | 2530 // arguments. |
2532 | 2531 |
(...skipping 19 matching lines...) Expand all Loading... |
2552 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); | 2551 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); |
2553 | 2552 |
2554 // Record call targets in unoptimized code, but not in the snapshot. | 2553 // Record call targets in unoptimized code, but not in the snapshot. |
2555 __ EmitLoadTypeFeedbackVector(rbx); | 2554 __ EmitLoadTypeFeedbackVector(rbx); |
2556 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2555 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot())); |
2557 | 2556 |
2558 CallConstructStub stub(isolate()); | 2557 CallConstructStub stub(isolate()); |
2559 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2558 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
2560 OperandStackDepthDecrement(arg_count + 1); | 2559 OperandStackDepthDecrement(arg_count + 1); |
2561 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2560 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2562 // Restore context register. | 2561 RestoreContext(); |
2563 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2564 context()->Plug(rax); | 2562 context()->Plug(rax); |
2565 } | 2563 } |
2566 | 2564 |
2567 | 2565 |
2568 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2566 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2569 SuperCallReference* super_call_ref = | 2567 SuperCallReference* super_call_ref = |
2570 expr->expression()->AsSuperCallReference(); | 2568 expr->expression()->AsSuperCallReference(); |
2571 DCHECK_NOT_NULL(super_call_ref); | 2569 DCHECK_NOT_NULL(super_call_ref); |
2572 | 2570 |
2573 // Push the super constructor target on the stack (may be null, | 2571 // Push the super constructor target on the stack (may be null, |
(...skipping 20 matching lines...) Expand all Loading... |
2594 __ movp(rdx, result_register()); | 2592 __ movp(rdx, result_register()); |
2595 | 2593 |
2596 // Load function and argument count into rdi and rax. | 2594 // Load function and argument count into rdi and rax. |
2597 __ Set(rax, arg_count); | 2595 __ Set(rax, arg_count); |
2598 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); | 2596 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); |
2599 | 2597 |
2600 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2598 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2601 OperandStackDepthDecrement(arg_count + 1); | 2599 OperandStackDepthDecrement(arg_count + 1); |
2602 | 2600 |
2603 RecordJSReturnSite(expr); | 2601 RecordJSReturnSite(expr); |
2604 | 2602 RestoreContext(); |
2605 // Restore context register. | |
2606 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2607 | |
2608 context()->Plug(rax); | 2603 context()->Plug(rax); |
2609 } | 2604 } |
2610 | 2605 |
2611 | 2606 |
2612 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2607 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2613 ZoneList<Expression*>* args = expr->arguments(); | 2608 ZoneList<Expression*>* args = expr->arguments(); |
2614 DCHECK(args->length() == 1); | 2609 DCHECK(args->length() == 1); |
2615 | 2610 |
2616 VisitForAccumulatorValue(args->at(0)); | 2611 VisitForAccumulatorValue(args->at(0)); |
2617 | 2612 |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2996 VisitForStackValue(arg); | 2991 VisitForStackValue(arg); |
2997 } | 2992 } |
2998 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2993 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2999 // Move target to rdi. | 2994 // Move target to rdi. |
3000 int const argc = args->length() - 2; | 2995 int const argc = args->length() - 2; |
3001 __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize)); | 2996 __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize)); |
3002 // Call the target. | 2997 // Call the target. |
3003 __ Set(rax, argc); | 2998 __ Set(rax, argc); |
3004 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2999 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
3005 OperandStackDepthDecrement(argc + 1); | 3000 OperandStackDepthDecrement(argc + 1); |
3006 // Restore context register. | 3001 RestoreContext(); |
3007 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
3008 // Discard the function left on TOS. | 3002 // Discard the function left on TOS. |
3009 context()->DropAndPlug(1, rax); | 3003 context()->DropAndPlug(1, rax); |
3010 } | 3004 } |
3011 | 3005 |
3012 | 3006 |
3013 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3007 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3014 ZoneList<Expression*>* args = expr->arguments(); | 3008 ZoneList<Expression*>* args = expr->arguments(); |
3015 DCHECK(args->length() == 1); | 3009 DCHECK(args->length() == 1); |
3016 | 3010 |
3017 VisitForAccumulatorValue(args->at(0)); | 3011 VisitForAccumulatorValue(args->at(0)); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3116 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3110 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3117 ZoneList<Expression*>* args = expr->arguments(); | 3111 ZoneList<Expression*>* args = expr->arguments(); |
3118 int arg_count = args->length(); | 3112 int arg_count = args->length(); |
3119 | 3113 |
3120 SetCallPosition(expr); | 3114 SetCallPosition(expr); |
3121 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 3115 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
3122 __ Set(rax, arg_count); | 3116 __ Set(rax, arg_count); |
3123 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3117 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3124 RelocInfo::CODE_TARGET); | 3118 RelocInfo::CODE_TARGET); |
3125 OperandStackDepthDecrement(arg_count + 1); | 3119 OperandStackDepthDecrement(arg_count + 1); |
3126 | 3120 RestoreContext(); |
3127 // Restore context register. | |
3128 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
3129 } | 3121 } |
3130 | 3122 |
3131 | 3123 |
3132 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3124 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3133 switch (expr->op()) { | 3125 switch (expr->op()) { |
3134 case Token::DELETE: { | 3126 case Token::DELETE: { |
3135 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3127 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3136 Property* property = expr->expression()->AsProperty(); | 3128 Property* property = expr->expression()->AsProperty(); |
3137 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3129 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3138 | 3130 |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3590 Label* fall_through = NULL; | 3582 Label* fall_through = NULL; |
3591 context()->PrepareTest(&materialize_true, &materialize_false, | 3583 context()->PrepareTest(&materialize_true, &materialize_false, |
3592 &if_true, &if_false, &fall_through); | 3584 &if_true, &if_false, &fall_through); |
3593 | 3585 |
3594 Token::Value op = expr->op(); | 3586 Token::Value op = expr->op(); |
3595 VisitForStackValue(expr->left()); | 3587 VisitForStackValue(expr->left()); |
3596 switch (op) { | 3588 switch (op) { |
3597 case Token::IN: | 3589 case Token::IN: |
3598 VisitForStackValue(expr->right()); | 3590 VisitForStackValue(expr->right()); |
3599 SetExpressionPosition(expr); | 3591 SetExpressionPosition(expr); |
3600 CallRuntimeWithOperands(Runtime::kHasProperty); | 3592 EmitHasProperty(); |
3601 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3593 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3602 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 3594 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
3603 Split(equal, if_true, if_false, fall_through); | 3595 Split(equal, if_true, if_false, fall_through); |
3604 break; | 3596 break; |
3605 | 3597 |
3606 case Token::INSTANCEOF: { | 3598 case Token::INSTANCEOF: { |
3607 VisitForAccumulatorValue(expr->right()); | 3599 VisitForAccumulatorValue(expr->right()); |
3608 SetExpressionPosition(expr); | 3600 SetExpressionPosition(expr); |
3609 PopOperand(rdx); | 3601 PopOperand(rdx); |
3610 InstanceOfStub stub(isolate()); | 3602 InstanceOfStub stub(isolate()); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3855 DCHECK_EQ( | 3847 DCHECK_EQ( |
3856 isolate->builtins()->OnStackReplacement()->entry(), | 3848 isolate->builtins()->OnStackReplacement()->entry(), |
3857 Assembler::target_address_at(call_target_address, unoptimized_code)); | 3849 Assembler::target_address_at(call_target_address, unoptimized_code)); |
3858 return ON_STACK_REPLACEMENT; | 3850 return ON_STACK_REPLACEMENT; |
3859 } | 3851 } |
3860 | 3852 |
3861 } // namespace internal | 3853 } // namespace internal |
3862 } // namespace v8 | 3854 } // namespace v8 |
3863 | 3855 |
3864 #endif // V8_TARGET_ARCH_X64 | 3856 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |