Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 527963002: Implement loads and calls from 'super' (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased before landing Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 context()->Plug(rax); 1305 context()->Plug(rax);
1306 } 1306 }
1307 1307
1308 1308
1309 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1309 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1310 Comment cmnt(masm_, "[ VariableProxy"); 1310 Comment cmnt(masm_, "[ VariableProxy");
1311 EmitVariableLoad(expr); 1311 EmitVariableLoad(expr);
1312 } 1312 }
1313 1313
1314 1314
1315 void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
1316 Comment cnmt(masm_, "[ SuperReference ");
1317
1318 __ movp(LoadDescriptor::ReceiverRegister(),
1319 Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1320
1321 Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
1322 __ Move(LoadDescriptor::NameRegister(), home_object_symbol);
1323
1324 CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
1325
1326 __ Cmp(rax, isolate()->factory()->undefined_value());
1327 Label done;
1328 __ j(not_equal, &done);
1329 __ CallRuntime(Runtime::kThrowNonMethodError, 0);
1330 __ bind(&done);
1331 }
1332
1333
1315 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1334 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1316 TypeofState typeof_state, 1335 TypeofState typeof_state,
1317 Label* slow) { 1336 Label* slow) {
1318 Register context = rsi; 1337 Register context = rsi;
1319 Register temp = rdx; 1338 Register temp = rdx;
1320 1339
1321 Scope* s = scope(); 1340 Scope* s = scope();
1322 while (s != NULL) { 1341 while (s != NULL) {
1323 if (s->num_heap_slots() > 0) { 1342 if (s->num_heap_slots() > 0) {
1324 if (s->calls_sloppy_eval()) { 1343 if (s->calls_sloppy_eval()) {
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 if (FLAG_vector_ics) { 2275 if (FLAG_vector_ics) {
2257 __ Move(VectorLoadICDescriptor::SlotRegister(), 2276 __ Move(VectorLoadICDescriptor::SlotRegister(),
2258 Smi::FromInt(prop->PropertyFeedbackSlot())); 2277 Smi::FromInt(prop->PropertyFeedbackSlot()));
2259 CallLoadIC(NOT_CONTEXTUAL); 2278 CallLoadIC(NOT_CONTEXTUAL);
2260 } else { 2279 } else {
2261 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2280 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2262 } 2281 }
2263 } 2282 }
2264 2283
2265 2284
2285 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2286 SetSourcePosition(prop->position());
2287 Literal* key = prop->key()->AsLiteral();
2288 DCHECK(!key->value()->IsSmi());
2289 DCHECK(prop->IsSuperAccess());
2290
2291 SuperReference* super_ref = prop->obj()->AsSuperReference();
2292 EmitLoadHomeObject(super_ref);
2293 __ Push(rax);
2294 VisitForStackValue(super_ref->this_var());
2295 __ Push(key->value());
2296 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2297 }
2298
2299
2266 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2300 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2267 SetSourcePosition(prop->position()); 2301 SetSourcePosition(prop->position());
2268 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2302 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2269 if (FLAG_vector_ics) { 2303 if (FLAG_vector_ics) {
2270 __ Move(VectorLoadICDescriptor::SlotRegister(), 2304 __ Move(VectorLoadICDescriptor::SlotRegister(),
2271 Smi::FromInt(prop->PropertyFeedbackSlot())); 2305 Smi::FromInt(prop->PropertyFeedbackSlot()));
2272 CallIC(ic); 2306 CallIC(ic);
2273 } else { 2307 } else {
2274 CallIC(ic, prop->PropertyFeedbackId()); 2308 CallIC(ic, prop->PropertyFeedbackId());
2275 } 2309 }
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2506 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2540 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2507 context()->Plug(rax); 2541 context()->Plug(rax);
2508 } 2542 }
2509 2543
2510 2544
2511 void FullCodeGenerator::VisitProperty(Property* expr) { 2545 void FullCodeGenerator::VisitProperty(Property* expr) {
2512 Comment cmnt(masm_, "[ Property"); 2546 Comment cmnt(masm_, "[ Property");
2513 Expression* key = expr->key(); 2547 Expression* key = expr->key();
2514 2548
2515 if (key->IsPropertyName()) { 2549 if (key->IsPropertyName()) {
2516 VisitForAccumulatorValue(expr->obj()); 2550 if (!expr->IsSuperAccess()) {
2517 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister())); 2551 VisitForAccumulatorValue(expr->obj());
2518 __ movp(LoadDescriptor::ReceiverRegister(), rax); 2552 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister()));
2519 EmitNamedPropertyLoad(expr); 2553 __ movp(LoadDescriptor::ReceiverRegister(), rax);
2554 EmitNamedPropertyLoad(expr);
2555 } else {
2556 EmitNamedSuperPropertyLoad(expr);
2557 }
2520 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2558 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2521 context()->Plug(rax); 2559 context()->Plug(rax);
2522 } else { 2560 } else {
2523 VisitForStackValue(expr->obj()); 2561 VisitForStackValue(expr->obj());
2524 VisitForAccumulatorValue(expr->key()); 2562 VisitForAccumulatorValue(expr->key());
2525 __ Move(LoadDescriptor::NameRegister(), rax); 2563 __ Move(LoadDescriptor::NameRegister(), rax);
2526 __ Pop(LoadDescriptor::ReceiverRegister()); 2564 __ Pop(LoadDescriptor::ReceiverRegister());
2527 EmitKeyedPropertyLoad(expr); 2565 EmitKeyedPropertyLoad(expr);
2528 context()->Plug(rax); 2566 context()->Plug(rax);
2529 } 2567 }
(...skipping 18 matching lines...) Expand all
2548 { StackValueContext context(this); 2586 { StackValueContext context(this);
2549 EmitVariableLoad(callee->AsVariableProxy()); 2587 EmitVariableLoad(callee->AsVariableProxy());
2550 PrepareForBailout(callee, NO_REGISTERS); 2588 PrepareForBailout(callee, NO_REGISTERS);
2551 } 2589 }
2552 // Push undefined as receiver. This is patched in the method prologue if it 2590 // Push undefined as receiver. This is patched in the method prologue if it
2553 // is a sloppy mode method. 2591 // is a sloppy mode method.
2554 __ Push(isolate()->factory()->undefined_value()); 2592 __ Push(isolate()->factory()->undefined_value());
2555 } else { 2593 } else {
2556 // Load the function from the receiver. 2594 // Load the function from the receiver.
2557 DCHECK(callee->IsProperty()); 2595 DCHECK(callee->IsProperty());
2596 DCHECK(!callee->AsProperty()->IsSuperAccess());
2558 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 2597 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2559 EmitNamedPropertyLoad(callee->AsProperty()); 2598 EmitNamedPropertyLoad(callee->AsProperty());
2560 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2599 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2561 // Push the target function under the receiver. 2600 // Push the target function under the receiver.
2562 __ Push(Operand(rsp, 0)); 2601 __ Push(Operand(rsp, 0));
2563 __ movp(Operand(rsp, kPointerSize), rax); 2602 __ movp(Operand(rsp, kPointerSize), rax);
2564 } 2603 }
2565 2604
2566 EmitCall(expr, call_type); 2605 EmitCall(expr, call_type);
2567 } 2606 }
2568 2607
2569 2608
2609 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2610 Expression* callee = expr->expression();
2611 DCHECK(callee->IsProperty());
2612 Property* prop = callee->AsProperty();
2613 DCHECK(prop->IsSuperAccess());
2614
2615 SetSourcePosition(prop->position());
2616 Literal* key = prop->key()->AsLiteral();
2617 DCHECK(!key->value()->IsSmi());
2618 // Load the function from the receiver.
2619 SuperReference* super_ref = prop->obj()->AsSuperReference();
2620 EmitLoadHomeObject(super_ref);
2621 __ Push(rax);
2622 VisitForAccumulatorValue(super_ref->this_var());
2623 __ Push(rax);
2624 __ Push(Operand(rsp, kPointerSize));
2625 __ Push(rax);
2626 __ Push(key->value());
2627
2628 // Stack here:
2629 // - home_object
2630 // - this (receiver)
2631 // - home_object <-- LoadFromSuper will pop here and below.
2632 // - this (receiver)
2633 // - key
2634 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2635
2636 // Replace home_object with target function.
2637 __ movp(Operand(rsp, kPointerSize), rax);
2638
2639 // Stack here:
2640 // - target function
2641 // - this (receiver)
2642 EmitCall(expr, CallICState::METHOD);
2643 }
2644
2645
2570 // Common code for calls using the IC. 2646 // Common code for calls using the IC.
2571 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2647 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2572 Expression* key) { 2648 Expression* key) {
2573 // Load the key. 2649 // Load the key.
2574 VisitForAccumulatorValue(key); 2650 VisitForAccumulatorValue(key);
2575 2651
2576 Expression* callee = expr->expression(); 2652 Expression* callee = expr->expression();
2577 2653
2578 // Load the function from the receiver. 2654 // Load the function from the receiver.
2579 DCHECK(callee->IsProperty()); 2655 DCHECK(callee->IsProperty());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 // passing the hole to the call function stub. 2797 // passing the hole to the call function stub.
2722 __ PushRoot(Heap::kUndefinedValueRootIndex); 2798 __ PushRoot(Heap::kUndefinedValueRootIndex);
2723 __ bind(&call); 2799 __ bind(&call);
2724 } 2800 }
2725 2801
2726 // The receiver is either the global receiver or an object found by 2802 // The receiver is either the global receiver or an object found by
2727 // LoadContextSlot. 2803 // LoadContextSlot.
2728 EmitCall(expr); 2804 EmitCall(expr);
2729 } else if (call_type == Call::PROPERTY_CALL) { 2805 } else if (call_type == Call::PROPERTY_CALL) {
2730 Property* property = callee->AsProperty(); 2806 Property* property = callee->AsProperty();
2731 { PreservePositionScope scope(masm()->positions_recorder()); 2807 bool is_named_call = property->key()->IsPropertyName();
2732 VisitForStackValue(property->obj()); 2808 // super.x() is handled in EmitCallWithLoadIC.
2733 } 2809 if (property->IsSuperAccess() && is_named_call) {
2734 if (property->key()->IsPropertyName()) { 2810 EmitSuperCallWithLoadIC(expr);
2735 EmitCallWithLoadIC(expr);
2736 } else { 2811 } else {
2737 EmitKeyedCallWithLoadIC(expr, property->key()); 2812 {
2813 PreservePositionScope scope(masm()->positions_recorder());
2814 VisitForStackValue(property->obj());
2815 }
2816 if (is_named_call) {
2817 EmitCallWithLoadIC(expr);
2818 } else {
2819 EmitKeyedCallWithLoadIC(expr, property->key());
2820 }
2738 } 2821 }
2739 } else { 2822 } else {
2740 DCHECK(call_type == Call::OTHER_CALL); 2823 DCHECK(call_type == Call::OTHER_CALL);
2741 // Call to an arbitrary expression not handled specially above. 2824 // Call to an arbitrary expression not handled specially above.
2742 { PreservePositionScope scope(masm()->positions_recorder()); 2825 { PreservePositionScope scope(masm()->positions_recorder());
2743 VisitForStackValue(callee); 2826 VisitForStackValue(callee);
2744 } 2827 }
2745 __ PushRoot(Heap::kUndefinedValueRootIndex); 2828 __ PushRoot(Heap::kUndefinedValueRootIndex);
2746 // Emit function call. 2829 // Emit function call.
2747 EmitCall(expr); 2830 EmitCall(expr);
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after
4833 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4916 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4834 Assembler::target_address_at(call_target_address, 4917 Assembler::target_address_at(call_target_address,
4835 unoptimized_code)); 4918 unoptimized_code));
4836 return OSR_AFTER_STACK_CHECK; 4919 return OSR_AFTER_STACK_CHECK;
4837 } 4920 }
4838 4921
4839 4922
4840 } } // namespace v8::internal 4923 } } // namespace v8::internal
4841 4924
4842 #endif // V8_TARGET_ARCH_X64 4925 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/runtime.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698