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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |