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