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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 context()->Plug(v0); | 1335 context()->Plug(v0); |
1336 } | 1336 } |
1337 | 1337 |
1338 | 1338 |
1339 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1339 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1340 Comment cmnt(masm_, "[ VariableProxy"); | 1340 Comment cmnt(masm_, "[ VariableProxy"); |
1341 EmitVariableLoad(expr); | 1341 EmitVariableLoad(expr); |
1342 } | 1342 } |
1343 | 1343 |
1344 | 1344 |
| 1345 void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { |
| 1346 Comment cnmt(masm_, "[ SuperReference "); |
| 1347 |
| 1348 __ lw(LoadDescriptor::ReceiverRegister(), |
| 1349 MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1350 |
| 1351 Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol()); |
| 1352 __ li(LoadDescriptor::NameRegister(), home_object_symbol); |
| 1353 |
| 1354 CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); |
| 1355 |
| 1356 Label done; |
| 1357 __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value())); |
| 1358 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1359 __ bind(&done); |
| 1360 } |
| 1361 |
| 1362 |
1345 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1363 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1346 TypeofState typeof_state, | 1364 TypeofState typeof_state, |
1347 Label* slow) { | 1365 Label* slow) { |
1348 Register current = cp; | 1366 Register current = cp; |
1349 Register next = a1; | 1367 Register next = a1; |
1350 Register temp = a2; | 1368 Register temp = a2; |
1351 | 1369 |
1352 Scope* s = scope(); | 1370 Scope* s = scope(); |
1353 while (s != NULL) { | 1371 while (s != NULL) { |
1354 if (s->num_heap_slots() > 0) { | 1372 if (s->num_heap_slots() > 0) { |
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2274 // Only the value field needs a write barrier, as the other values are in the | 2292 // Only the value field needs a write barrier, as the other values are in the |
2275 // root set. | 2293 // root set. |
2276 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, | 2294 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, |
2277 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2295 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
2278 } | 2296 } |
2279 | 2297 |
2280 | 2298 |
2281 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2299 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2282 SetSourcePosition(prop->position()); | 2300 SetSourcePosition(prop->position()); |
2283 Literal* key = prop->key()->AsLiteral(); | 2301 Literal* key = prop->key()->AsLiteral(); |
| 2302 |
2284 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); | 2303 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); |
2285 if (FLAG_vector_ics) { | 2304 if (FLAG_vector_ics) { |
2286 __ li(VectorLoadICDescriptor::SlotRegister(), | 2305 __ li(VectorLoadICDescriptor::SlotRegister(), |
2287 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2306 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2288 CallLoadIC(NOT_CONTEXTUAL); | 2307 CallLoadIC(NOT_CONTEXTUAL); |
2289 } else { | 2308 } else { |
2290 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2309 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2291 } | 2310 } |
2292 } | 2311 } |
2293 | 2312 |
2294 | 2313 |
| 2314 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2315 SetSourcePosition(prop->position()); |
| 2316 Literal* key = prop->key()->AsLiteral(); |
| 2317 DCHECK(!key->value()->IsSmi()); |
| 2318 DCHECK(prop->IsSuperAccess()); |
| 2319 |
| 2320 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
| 2321 EmitLoadHomeObject(super_ref); |
| 2322 __ Push(v0); |
| 2323 VisitForStackValue(super_ref->this_var()); |
| 2324 __ Push(key->value()); |
| 2325 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
| 2326 } |
| 2327 |
| 2328 |
2295 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2329 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2296 SetSourcePosition(prop->position()); | 2330 SetSourcePosition(prop->position()); |
2297 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2331 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2298 if (FLAG_vector_ics) { | 2332 if (FLAG_vector_ics) { |
2299 __ li(VectorLoadICDescriptor::SlotRegister(), | 2333 __ li(VectorLoadICDescriptor::SlotRegister(), |
2300 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2334 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2301 CallIC(ic); | 2335 CallIC(ic); |
2302 } else { | 2336 } else { |
2303 CallIC(ic, prop->PropertyFeedbackId()); | 2337 CallIC(ic, prop->PropertyFeedbackId()); |
2304 } | 2338 } |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2612 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2579 context()->Plug(v0); | 2613 context()->Plug(v0); |
2580 } | 2614 } |
2581 | 2615 |
2582 | 2616 |
2583 void FullCodeGenerator::VisitProperty(Property* expr) { | 2617 void FullCodeGenerator::VisitProperty(Property* expr) { |
2584 Comment cmnt(masm_, "[ Property"); | 2618 Comment cmnt(masm_, "[ Property"); |
2585 Expression* key = expr->key(); | 2619 Expression* key = expr->key(); |
2586 | 2620 |
2587 if (key->IsPropertyName()) { | 2621 if (key->IsPropertyName()) { |
2588 VisitForAccumulatorValue(expr->obj()); | 2622 if (!expr->IsSuperAccess()) { |
2589 __ Move(LoadDescriptor::ReceiverRegister(), v0); | 2623 VisitForAccumulatorValue(expr->obj()); |
2590 EmitNamedPropertyLoad(expr); | 2624 __ Move(LoadDescriptor::ReceiverRegister(), v0); |
| 2625 EmitNamedPropertyLoad(expr); |
| 2626 } else { |
| 2627 EmitNamedSuperPropertyLoad(expr); |
| 2628 } |
2591 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2629 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2592 context()->Plug(v0); | 2630 context()->Plug(v0); |
2593 } else { | 2631 } else { |
2594 VisitForStackValue(expr->obj()); | 2632 VisitForStackValue(expr->obj()); |
2595 VisitForAccumulatorValue(expr->key()); | 2633 VisitForAccumulatorValue(expr->key()); |
2596 __ Move(LoadDescriptor::NameRegister(), v0); | 2634 __ Move(LoadDescriptor::NameRegister(), v0); |
2597 __ pop(LoadDescriptor::ReceiverRegister()); | 2635 __ pop(LoadDescriptor::ReceiverRegister()); |
2598 EmitKeyedPropertyLoad(expr); | 2636 EmitKeyedPropertyLoad(expr); |
2599 context()->Plug(v0); | 2637 context()->Plug(v0); |
2600 } | 2638 } |
(...skipping 19 matching lines...) Expand all Loading... |
2620 { StackValueContext context(this); | 2658 { StackValueContext context(this); |
2621 EmitVariableLoad(callee->AsVariableProxy()); | 2659 EmitVariableLoad(callee->AsVariableProxy()); |
2622 PrepareForBailout(callee, NO_REGISTERS); | 2660 PrepareForBailout(callee, NO_REGISTERS); |
2623 } | 2661 } |
2624 // Push undefined as receiver. This is patched in the method prologue if it | 2662 // Push undefined as receiver. This is patched in the method prologue if it |
2625 // is a sloppy mode method. | 2663 // is a sloppy mode method. |
2626 __ Push(isolate()->factory()->undefined_value()); | 2664 __ Push(isolate()->factory()->undefined_value()); |
2627 } else { | 2665 } else { |
2628 // Load the function from the receiver. | 2666 // Load the function from the receiver. |
2629 DCHECK(callee->IsProperty()); | 2667 DCHECK(callee->IsProperty()); |
| 2668 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2630 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2669 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
2631 EmitNamedPropertyLoad(callee->AsProperty()); | 2670 EmitNamedPropertyLoad(callee->AsProperty()); |
2632 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2671 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2633 // Push the target function under the receiver. | 2672 // Push the target function under the receiver. |
2634 __ lw(at, MemOperand(sp, 0)); | 2673 __ lw(at, MemOperand(sp, 0)); |
2635 __ push(at); | 2674 __ push(at); |
2636 __ sw(v0, MemOperand(sp, kPointerSize)); | 2675 __ sw(v0, MemOperand(sp, kPointerSize)); |
2637 } | 2676 } |
2638 | 2677 |
2639 EmitCall(expr, call_type); | 2678 EmitCall(expr, call_type); |
2640 } | 2679 } |
2641 | 2680 |
2642 | 2681 |
| 2682 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2683 Expression* callee = expr->expression(); |
| 2684 DCHECK(callee->IsProperty()); |
| 2685 Property* prop = callee->AsProperty(); |
| 2686 DCHECK(prop->IsSuperAccess()); |
| 2687 |
| 2688 SetSourcePosition(prop->position()); |
| 2689 Literal* key = prop->key()->AsLiteral(); |
| 2690 DCHECK(!key->value()->IsSmi()); |
| 2691 // Load the function from the receiver. |
| 2692 const Register scratch = a1; |
| 2693 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
| 2694 EmitLoadHomeObject(super_ref); |
| 2695 __ Push(v0); |
| 2696 VisitForAccumulatorValue(super_ref->this_var()); |
| 2697 __ Push(v0); |
| 2698 __ lw(scratch, MemOperand(sp, kPointerSize)); |
| 2699 __ Push(scratch, v0); |
| 2700 __ Push(key->value()); |
| 2701 |
| 2702 // Stack here: |
| 2703 // - home_object |
| 2704 // - this (receiver) |
| 2705 // - home_object <-- LoadFromSuper will pop here and below. |
| 2706 // - this (receiver) |
| 2707 // - key |
| 2708 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
| 2709 |
| 2710 // Replace home_object with target function. |
| 2711 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2712 |
| 2713 // Stack here: |
| 2714 // - target function |
| 2715 // - this (receiver) |
| 2716 EmitCall(expr, CallICState::METHOD); |
| 2717 } |
| 2718 |
| 2719 |
2643 // Code common for calls using the IC. | 2720 // Code common for calls using the IC. |
2644 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2721 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2645 Expression* key) { | 2722 Expression* key) { |
2646 // Load the key. | 2723 // Load the key. |
2647 VisitForAccumulatorValue(key); | 2724 VisitForAccumulatorValue(key); |
2648 | 2725 |
2649 Expression* callee = expr->expression(); | 2726 Expression* callee = expr->expression(); |
2650 | 2727 |
2651 // Load the function from the receiver. | 2728 // Load the function from the receiver. |
2652 DCHECK(callee->IsProperty()); | 2729 DCHECK(callee->IsProperty()); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2800 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 2877 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
2801 __ push(a1); | 2878 __ push(a1); |
2802 __ bind(&call); | 2879 __ bind(&call); |
2803 } | 2880 } |
2804 | 2881 |
2805 // The receiver is either the global receiver or an object found | 2882 // The receiver is either the global receiver or an object found |
2806 // by LoadContextSlot. | 2883 // by LoadContextSlot. |
2807 EmitCall(expr); | 2884 EmitCall(expr); |
2808 } else if (call_type == Call::PROPERTY_CALL) { | 2885 } else if (call_type == Call::PROPERTY_CALL) { |
2809 Property* property = callee->AsProperty(); | 2886 Property* property = callee->AsProperty(); |
2810 { PreservePositionScope scope(masm()->positions_recorder()); | 2887 bool is_named_call = property->key()->IsPropertyName(); |
2811 VisitForStackValue(property->obj()); | 2888 // super.x() is handled in EmitCallWithLoadIC. |
2812 } | 2889 if (property->IsSuperAccess() && is_named_call) { |
2813 if (property->key()->IsPropertyName()) { | 2890 EmitSuperCallWithLoadIC(expr); |
2814 EmitCallWithLoadIC(expr); | |
2815 } else { | 2891 } else { |
2816 EmitKeyedCallWithLoadIC(expr, property->key()); | 2892 { |
| 2893 PreservePositionScope scope(masm()->positions_recorder()); |
| 2894 VisitForStackValue(property->obj()); |
| 2895 } |
| 2896 if (is_named_call) { |
| 2897 EmitCallWithLoadIC(expr); |
| 2898 } else { |
| 2899 EmitKeyedCallWithLoadIC(expr, property->key()); |
| 2900 } |
2817 } | 2901 } |
2818 } else { | 2902 } else { |
2819 DCHECK(call_type == Call::OTHER_CALL); | 2903 DCHECK(call_type == Call::OTHER_CALL); |
2820 // Call to an arbitrary expression not handled specially above. | 2904 // Call to an arbitrary expression not handled specially above. |
2821 { PreservePositionScope scope(masm()->positions_recorder()); | 2905 { PreservePositionScope scope(masm()->positions_recorder()); |
2822 VisitForStackValue(callee); | 2906 VisitForStackValue(callee); |
2823 } | 2907 } |
2824 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 2908 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
2825 __ push(a1); | 2909 __ push(a1); |
2826 // Emit function call. | 2910 // Emit function call. |
(...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4872 Assembler::target_address_at(pc_immediate_load_address)) == | 4956 Assembler::target_address_at(pc_immediate_load_address)) == |
4873 reinterpret_cast<uint32_t>( | 4957 reinterpret_cast<uint32_t>( |
4874 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4958 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4875 return OSR_AFTER_STACK_CHECK; | 4959 return OSR_AFTER_STACK_CHECK; |
4876 } | 4960 } |
4877 | 4961 |
4878 | 4962 |
4879 } } // namespace v8::internal | 4963 } } // namespace v8::internal |
4880 | 4964 |
4881 #endif // V8_TARGET_ARCH_MIPS | 4965 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |