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

Side by Side Diff: src/arm/full-codegen-arm.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 | « no previous file | src/arm64/full-codegen-arm64.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_ARM 7 #if V8_TARGET_ARCH_ARM
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 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 context()->Plug(r0); 1348 context()->Plug(r0);
1349 } 1349 }
1350 1350
1351 1351
1352 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1352 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1353 Comment cmnt(masm_, "[ VariableProxy"); 1353 Comment cmnt(masm_, "[ VariableProxy");
1354 EmitVariableLoad(expr); 1354 EmitVariableLoad(expr);
1355 } 1355 }
1356 1356
1357 1357
1358 void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
1359 Comment cnmt(masm_, "[ SuperReference ");
1360
1361 __ ldr(LoadDescriptor::ReceiverRegister(),
1362 MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1363
1364 Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
1365 __ Move(LoadDescriptor::NameRegister(), home_object_symbol);
1366
1367 CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
1368
1369 __ cmp(r0, Operand(isolate()->factory()->undefined_value()));
1370 Label done;
1371 __ b(ne, &done);
1372 __ CallRuntime(Runtime::kThrowNonMethodError, 0);
1373 __ bind(&done);
1374 }
1375
1376
1358 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1377 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1359 TypeofState typeof_state, 1378 TypeofState typeof_state,
1360 Label* slow) { 1379 Label* slow) {
1361 Register current = cp; 1380 Register current = cp;
1362 Register next = r1; 1381 Register next = r1;
1363 Register temp = r2; 1382 Register temp = r2;
1364 1383
1365 Scope* s = scope(); 1384 Scope* s = scope();
1366 while (s != NULL) { 1385 while (s != NULL) {
1367 if (s->num_heap_slots() > 0) { 1386 if (s->num_heap_slots() > 0) {
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 // Only the value field needs a write barrier, as the other values are in the 2312 // Only the value field needs a write barrier, as the other values are in the
2294 // root set. 2313 // root set.
2295 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, 2314 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset,
2296 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); 2315 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs);
2297 } 2316 }
2298 2317
2299 2318
2300 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2319 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2301 SetSourcePosition(prop->position()); 2320 SetSourcePosition(prop->position());
2302 Literal* key = prop->key()->AsLiteral(); 2321 Literal* key = prop->key()->AsLiteral();
2322
2303 __ mov(LoadDescriptor::NameRegister(), Operand(key->value())); 2323 __ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
2304 if (FLAG_vector_ics) { 2324 if (FLAG_vector_ics) {
2305 __ mov(VectorLoadICDescriptor::SlotRegister(), 2325 __ mov(VectorLoadICDescriptor::SlotRegister(),
2306 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2326 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2307 CallLoadIC(NOT_CONTEXTUAL); 2327 CallLoadIC(NOT_CONTEXTUAL);
2308 } else { 2328 } else {
2309 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2329 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2310 } 2330 }
2311 } 2331 }
2312 2332
2313 2333
2334 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2335 SetSourcePosition(prop->position());
2336 Literal* key = prop->key()->AsLiteral();
2337 DCHECK(!key->value()->IsSmi());
2338 DCHECK(prop->IsSuperAccess());
2339
2340 SuperReference* super_ref = prop->obj()->AsSuperReference();
2341 EmitLoadHomeObject(super_ref);
2342 __ Push(r0);
2343 VisitForStackValue(super_ref->this_var());
2344 __ Push(key->value());
2345 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2346 }
2347
2348
2314 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2349 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2315 SetSourcePosition(prop->position()); 2350 SetSourcePosition(prop->position());
2316 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2351 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2317 if (FLAG_vector_ics) { 2352 if (FLAG_vector_ics) {
2318 __ mov(VectorLoadICDescriptor::SlotRegister(), 2353 __ mov(VectorLoadICDescriptor::SlotRegister(),
2319 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2354 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2320 CallIC(ic); 2355 CallIC(ic);
2321 } else { 2356 } else {
2322 CallIC(ic, prop->PropertyFeedbackId()); 2357 CallIC(ic, prop->PropertyFeedbackId());
2323 } 2358 }
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2591 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2626 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2592 context()->Plug(r0); 2627 context()->Plug(r0);
2593 } 2628 }
2594 2629
2595 2630
2596 void FullCodeGenerator::VisitProperty(Property* expr) { 2631 void FullCodeGenerator::VisitProperty(Property* expr) {
2597 Comment cmnt(masm_, "[ Property"); 2632 Comment cmnt(masm_, "[ Property");
2598 Expression* key = expr->key(); 2633 Expression* key = expr->key();
2599 2634
2600 if (key->IsPropertyName()) { 2635 if (key->IsPropertyName()) {
2601 VisitForAccumulatorValue(expr->obj()); 2636 if (!expr->IsSuperAccess()) {
2602 __ Move(LoadDescriptor::ReceiverRegister(), r0); 2637 VisitForAccumulatorValue(expr->obj());
2603 EmitNamedPropertyLoad(expr); 2638 __ Move(LoadDescriptor::ReceiverRegister(), r0);
2639 EmitNamedPropertyLoad(expr);
2640 } else {
2641 EmitNamedSuperPropertyLoad(expr);
2642 }
2604 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2643 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2605 context()->Plug(r0); 2644 context()->Plug(r0);
2606 } else { 2645 } else {
2607 VisitForStackValue(expr->obj()); 2646 VisitForStackValue(expr->obj());
2608 VisitForAccumulatorValue(expr->key()); 2647 VisitForAccumulatorValue(expr->key());
2609 __ Move(LoadDescriptor::NameRegister(), r0); 2648 __ Move(LoadDescriptor::NameRegister(), r0);
2610 __ pop(LoadDescriptor::ReceiverRegister()); 2649 __ pop(LoadDescriptor::ReceiverRegister());
2611 EmitKeyedPropertyLoad(expr); 2650 EmitKeyedPropertyLoad(expr);
2612 context()->Plug(r0); 2651 context()->Plug(r0);
2613 } 2652 }
(...skipping 22 matching lines...) Expand all
2636 { StackValueContext context(this); 2675 { StackValueContext context(this);
2637 EmitVariableLoad(callee->AsVariableProxy()); 2676 EmitVariableLoad(callee->AsVariableProxy());
2638 PrepareForBailout(callee, NO_REGISTERS); 2677 PrepareForBailout(callee, NO_REGISTERS);
2639 } 2678 }
2640 // Push undefined as receiver. This is patched in the method prologue if it 2679 // Push undefined as receiver. This is patched in the method prologue if it
2641 // is a sloppy mode method. 2680 // is a sloppy mode method.
2642 __ Push(isolate()->factory()->undefined_value()); 2681 __ Push(isolate()->factory()->undefined_value());
2643 } else { 2682 } else {
2644 // Load the function from the receiver. 2683 // Load the function from the receiver.
2645 DCHECK(callee->IsProperty()); 2684 DCHECK(callee->IsProperty());
2685 DCHECK(!callee->AsProperty()->IsSuperAccess());
2646 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2686 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2647 EmitNamedPropertyLoad(callee->AsProperty()); 2687 EmitNamedPropertyLoad(callee->AsProperty());
2648 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2688 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2649 // Push the target function under the receiver. 2689 // Push the target function under the receiver.
2650 __ ldr(ip, MemOperand(sp, 0)); 2690 __ ldr(ip, MemOperand(sp, 0));
2651 __ push(ip); 2691 __ push(ip);
2652 __ str(r0, MemOperand(sp, kPointerSize)); 2692 __ str(r0, MemOperand(sp, kPointerSize));
2653 } 2693 }
2654 2694
2655 EmitCall(expr, call_type); 2695 EmitCall(expr, call_type);
2656 } 2696 }
2657 2697
2658 2698
2699 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2700 Expression* callee = expr->expression();
2701 DCHECK(callee->IsProperty());
2702 Property* prop = callee->AsProperty();
2703 DCHECK(prop->IsSuperAccess());
2704
2705 SetSourcePosition(prop->position());
2706 Literal* key = prop->key()->AsLiteral();
2707 DCHECK(!key->value()->IsSmi());
2708 // Load the function from the receiver.
2709 const Register scratch = r1;
2710 SuperReference* super_ref = prop->obj()->AsSuperReference();
2711 EmitLoadHomeObject(super_ref);
2712 __ Push(r0);
2713 VisitForAccumulatorValue(super_ref->this_var());
2714 __ Push(r0);
2715 __ ldr(scratch, MemOperand(sp, kPointerSize));
2716 __ Push(scratch);
2717 __ Push(r0);
2718 __ Push(key->value());
2719
2720 // Stack here:
2721 // - home_object
2722 // - this (receiver)
2723 // - home_object <-- LoadFromSuper will pop here and below.
2724 // - this (receiver)
2725 // - key
2726 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2727
2728 // Replace home_object with target function.
2729 __ str(r0, MemOperand(sp, kPointerSize));
2730
2731 // Stack here:
2732 // - target function
2733 // - this (receiver)
2734 EmitCall(expr, CallICState::METHOD);
2735 }
2736
2737
2659 // Code common for calls using the IC. 2738 // Code common for calls using the IC.
2660 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2739 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2661 Expression* key) { 2740 Expression* key) {
2662 // Load the key. 2741 // Load the key.
2663 VisitForAccumulatorValue(key); 2742 VisitForAccumulatorValue(key);
2664 2743
2665 Expression* callee = expr->expression(); 2744 Expression* callee = expr->expression();
2666 2745
2667 // Load the function from the receiver. 2746 // Load the function from the receiver.
2668 DCHECK(callee->IsProperty()); 2747 DCHECK(callee->IsProperty());
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2818 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2897 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2819 __ push(r1); 2898 __ push(r1);
2820 __ bind(&call); 2899 __ bind(&call);
2821 } 2900 }
2822 2901
2823 // The receiver is either the global receiver or an object found 2902 // The receiver is either the global receiver or an object found
2824 // by LoadContextSlot. 2903 // by LoadContextSlot.
2825 EmitCall(expr); 2904 EmitCall(expr);
2826 } else if (call_type == Call::PROPERTY_CALL) { 2905 } else if (call_type == Call::PROPERTY_CALL) {
2827 Property* property = callee->AsProperty(); 2906 Property* property = callee->AsProperty();
2828 { PreservePositionScope scope(masm()->positions_recorder()); 2907 bool is_named_call = property->key()->IsPropertyName();
2829 VisitForStackValue(property->obj()); 2908 // super.x() is handled in EmitCallWithLoadIC.
2830 } 2909 if (property->IsSuperAccess() && is_named_call) {
2831 if (property->key()->IsPropertyName()) { 2910 EmitSuperCallWithLoadIC(expr);
2832 EmitCallWithLoadIC(expr);
2833 } else { 2911 } else {
2834 EmitKeyedCallWithLoadIC(expr, property->key()); 2912 {
2913 PreservePositionScope scope(masm()->positions_recorder());
2914 VisitForStackValue(property->obj());
2915 }
2916 if (is_named_call) {
2917 EmitCallWithLoadIC(expr);
2918 } else {
2919 EmitKeyedCallWithLoadIC(expr, property->key());
2920 }
2835 } 2921 }
2836 } else { 2922 } else {
2837 DCHECK(call_type == Call::OTHER_CALL); 2923 DCHECK(call_type == Call::OTHER_CALL);
2838 // Call to an arbitrary expression not handled specially above. 2924 // Call to an arbitrary expression not handled specially above.
2839 { PreservePositionScope scope(masm()->positions_recorder()); 2925 { PreservePositionScope scope(masm()->positions_recorder());
2840 VisitForStackValue(callee); 2926 VisitForStackValue(callee);
2841 } 2927 }
2842 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2928 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2843 __ push(r1); 2929 __ push(r1);
2844 // Emit function call. 2930 // Emit function call.
(...skipping 2077 matching lines...) Expand 10 before | Expand all | Expand 10 after
4922 5008
4923 DCHECK(interrupt_address == 5009 DCHECK(interrupt_address ==
4924 isolate->builtins()->OsrAfterStackCheck()->entry()); 5010 isolate->builtins()->OsrAfterStackCheck()->entry());
4925 return OSR_AFTER_STACK_CHECK; 5011 return OSR_AFTER_STACK_CHECK;
4926 } 5012 }
4927 5013
4928 5014
4929 } } // namespace v8::internal 5015 } } // namespace v8::internal
4930 5016
4931 #endif // V8_TARGET_ARCH_ARM 5017 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698