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 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 : KEYED_PROPERTY; | 1864 : KEYED_PROPERTY; |
1865 } | 1865 } |
1866 | 1866 |
1867 // Evaluate LHS expression. | 1867 // Evaluate LHS expression. |
1868 switch (assign_type) { | 1868 switch (assign_type) { |
1869 case VARIABLE: | 1869 case VARIABLE: |
1870 // Nothing to do here. | 1870 // Nothing to do here. |
1871 break; | 1871 break; |
1872 case NAMED_PROPERTY: | 1872 case NAMED_PROPERTY: |
1873 if (expr->is_compound()) { | 1873 if (expr->is_compound()) { |
1874 // We need the receiver both on the stack and in the accumulator. | 1874 // We need the receiver both on the stack and in the register. |
1875 VisitForAccumulatorValue(property->obj()); | 1875 VisitForStackValue(property->obj()); |
1876 __ push(result_register()); | 1876 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
1877 } else { | 1877 } else { |
1878 VisitForStackValue(property->obj()); | 1878 VisitForStackValue(property->obj()); |
1879 } | 1879 } |
1880 break; | 1880 break; |
1881 case KEYED_PROPERTY: | 1881 case KEYED_PROPERTY: |
1882 // We need the key and receiver on both the stack and in v0 and a1. | 1882 // We need the key and receiver on both the stack and in v0 and a1. |
1883 if (expr->is_compound()) { | 1883 if (expr->is_compound()) { |
1884 VisitForStackValue(property->obj()); | 1884 VisitForStackValue(property->obj()); |
1885 VisitForAccumulatorValue(property->key()); | 1885 VisitForStackValue(property->key()); |
1886 __ lw(a1, MemOperand(sp, 0)); | 1886 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize)); |
1887 __ push(v0); | 1887 __ lw(LoadIC::NameRegister(), MemOperand(sp, 0)); |
1888 } else { | 1888 } else { |
1889 VisitForStackValue(property->obj()); | 1889 VisitForStackValue(property->obj()); |
1890 VisitForStackValue(property->key()); | 1890 VisitForStackValue(property->key()); |
1891 } | 1891 } |
1892 break; | 1892 break; |
1893 } | 1893 } |
1894 | 1894 |
1895 // For compound assignments we need another deoptimization point after the | 1895 // For compound assignments we need another deoptimization point after the |
1896 // variable/property load. | 1896 // variable/property load. |
1897 if (expr->is_compound()) { | 1897 if (expr->is_compound()) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 | 2015 |
2016 case Yield::DELEGATING: { | 2016 case Yield::DELEGATING: { |
2017 VisitForStackValue(expr->generator_object()); | 2017 VisitForStackValue(expr->generator_object()); |
2018 | 2018 |
2019 // Initial stack layout is as follows: | 2019 // Initial stack layout is as follows: |
2020 // [sp + 1 * kPointerSize] iter | 2020 // [sp + 1 * kPointerSize] iter |
2021 // [sp + 0 * kPointerSize] g | 2021 // [sp + 0 * kPointerSize] g |
2022 | 2022 |
2023 Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 2023 Label l_catch, l_try, l_suspend, l_continuation, l_resume; |
2024 Label l_next, l_call; | 2024 Label l_next, l_call; |
| 2025 Register load_receiver = LoadIC::ReceiverRegister(); |
| 2026 Register load_name = LoadIC::NameRegister(); |
| 2027 |
2025 // Initial send value is undefined. | 2028 // Initial send value is undefined. |
2026 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); | 2029 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); |
2027 __ Branch(&l_next); | 2030 __ Branch(&l_next); |
2028 | 2031 |
2029 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 2032 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
2030 __ bind(&l_catch); | 2033 __ bind(&l_catch); |
2031 __ mov(a0, v0); | 2034 __ mov(a0, v0); |
2032 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 2035 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
2033 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" | 2036 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" |
2034 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2037 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
2035 __ Push(a2, a3, a0); // "throw", iter, except | 2038 __ Push(load_name, a3, a0); // "throw", iter, except |
2036 __ jmp(&l_call); | 2039 __ jmp(&l_call); |
2037 | 2040 |
2038 // try { received = %yield result } | 2041 // try { received = %yield result } |
2039 // Shuffle the received result above a try handler and yield it without | 2042 // Shuffle the received result above a try handler and yield it without |
2040 // re-boxing. | 2043 // re-boxing. |
2041 __ bind(&l_try); | 2044 __ bind(&l_try); |
2042 __ pop(a0); // result | 2045 __ pop(a0); // result |
2043 __ PushTryHandler(StackHandler::CATCH, expr->index()); | 2046 __ PushTryHandler(StackHandler::CATCH, expr->index()); |
2044 const int handler_size = StackHandlerConstants::kSize; | 2047 const int handler_size = StackHandlerConstants::kSize; |
2045 __ push(a0); // result | 2048 __ push(a0); // result |
(...skipping 15 matching lines...) Expand all Loading... |
2061 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2064 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
2062 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2065 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2063 __ pop(v0); // result | 2066 __ pop(v0); // result |
2064 EmitReturnSequence(); | 2067 EmitReturnSequence(); |
2065 __ mov(a0, v0); | 2068 __ mov(a0, v0); |
2066 __ bind(&l_resume); // received in a0 | 2069 __ bind(&l_resume); // received in a0 |
2067 __ PopTryHandler(); | 2070 __ PopTryHandler(); |
2068 | 2071 |
2069 // receiver = iter; f = 'next'; arg = received; | 2072 // receiver = iter; f = 'next'; arg = received; |
2070 __ bind(&l_next); | 2073 __ bind(&l_next); |
2071 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); | |
2072 Register keyedload_name = KeyedLoadIC::NameRegister(); | |
2073 ASSERT(keyedload_receiver.is(a1)); | |
2074 ASSERT(keyedload_name.is(a0)); | |
2075 | 2074 |
2076 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" | 2075 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" |
2077 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2076 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
2078 __ Push(a2, a3, a0); // "next", iter, received | 2077 __ Push(load_name, a3, a0); // "next", iter, received |
2079 | 2078 |
2080 // result = receiver[f](arg); | 2079 // result = receiver[f](arg); |
2081 __ bind(&l_call); | 2080 __ bind(&l_call); |
2082 __ lw(keyedload_receiver, MemOperand(sp, kPointerSize)); | 2081 __ lw(load_receiver, MemOperand(sp, kPointerSize)); |
2083 __ lw(keyedload_name, MemOperand(sp, 2 * kPointerSize)); | 2082 __ lw(load_name, MemOperand(sp, 2 * kPointerSize)); |
2084 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2083 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2085 CallIC(ic, TypeFeedbackId::None()); | 2084 CallIC(ic, TypeFeedbackId::None()); |
2086 __ mov(a0, v0); | 2085 __ mov(a0, v0); |
2087 __ mov(a1, a0); | 2086 __ mov(a1, a0); |
2088 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); | 2087 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); |
2089 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2088 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2090 __ CallStub(&stub); | 2089 __ CallStub(&stub); |
2091 | 2090 |
2092 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2091 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2093 __ Drop(1); // The function is still on the stack; drop it. | 2092 __ Drop(1); // The function is still on the stack; drop it. |
2094 | 2093 |
2095 // if (!result.done) goto l_try; | 2094 // if (!result.done) goto l_try; |
2096 Register load_receiver = LoadIC::ReceiverRegister(); | 2095 __ Move(load_receiver, v0); |
2097 Register load_name = LoadIC::NameRegister(); | |
2098 ASSERT(load_receiver.is(a0)); | |
2099 ASSERT(load_name.is(a2)); | |
2100 | 2096 |
2101 __ mov(load_receiver, v0); | 2097 __ push(load_receiver); // save result |
2102 __ push(v0); // save result | |
2103 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 2098 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
2104 CallLoadIC(NOT_CONTEXTUAL); // v0=result.done | 2099 CallLoadIC(NOT_CONTEXTUAL); // v0=result.done |
2105 __ mov(load_receiver, v0); | 2100 __ mov(a0, v0); |
2106 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2101 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2107 CallIC(bool_ic); | 2102 CallIC(bool_ic); |
2108 __ Branch(&l_try, eq, v0, Operand(zero_reg)); | 2103 __ Branch(&l_try, eq, v0, Operand(zero_reg)); |
2109 | 2104 |
2110 // result.value | 2105 // result.value |
2111 __ pop(load_receiver); // result | 2106 __ pop(load_receiver); // result |
2112 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 2107 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
2113 CallLoadIC(NOT_CONTEXTUAL); // v0=result.value | 2108 CallLoadIC(NOT_CONTEXTUAL); // v0=result.value |
2114 context()->DropAndPlug(2, v0); // drop iter and g | 2109 context()->DropAndPlug(2, v0); // drop iter and g |
2115 break; | 2110 break; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2265 // Only the value field needs a write barrier, as the other values are in the | 2260 // Only the value field needs a write barrier, as the other values are in the |
2266 // root set. | 2261 // root set. |
2267 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, | 2262 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, |
2268 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2263 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
2269 } | 2264 } |
2270 | 2265 |
2271 | 2266 |
2272 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2267 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2273 SetSourcePosition(prop->position()); | 2268 SetSourcePosition(prop->position()); |
2274 Literal* key = prop->key()->AsLiteral(); | 2269 Literal* key = prop->key()->AsLiteral(); |
2275 __ mov(LoadIC::ReceiverRegister(), result_register()); | |
2276 __ li(LoadIC::NameRegister(), Operand(key->value())); | 2270 __ li(LoadIC::NameRegister(), Operand(key->value())); |
2277 // Call load IC. It has register arguments receiver and property. | 2271 // Call load IC. It has register arguments receiver and property. |
2278 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2272 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2279 } | 2273 } |
2280 | 2274 |
2281 | 2275 |
2282 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2276 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2283 SetSourcePosition(prop->position()); | 2277 SetSourcePosition(prop->position()); |
2284 __ mov(a0, result_register()); | |
2285 // Call keyed load IC. It has register arguments receiver and key. | 2278 // Call keyed load IC. It has register arguments receiver and key. |
2286 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2279 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2287 CallIC(ic, prop->PropertyFeedbackId()); | 2280 CallIC(ic, prop->PropertyFeedbackId()); |
2288 } | 2281 } |
2289 | 2282 |
2290 | 2283 |
2291 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2284 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2292 Token::Value op, | 2285 Token::Value op, |
2293 OverwriteMode mode, | 2286 OverwriteMode mode, |
2294 Expression* left_expr, | 2287 Expression* left_expr, |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2573 context()->Plug(v0); | 2566 context()->Plug(v0); |
2574 } | 2567 } |
2575 | 2568 |
2576 | 2569 |
2577 void FullCodeGenerator::VisitProperty(Property* expr) { | 2570 void FullCodeGenerator::VisitProperty(Property* expr) { |
2578 Comment cmnt(masm_, "[ Property"); | 2571 Comment cmnt(masm_, "[ Property"); |
2579 Expression* key = expr->key(); | 2572 Expression* key = expr->key(); |
2580 | 2573 |
2581 if (key->IsPropertyName()) { | 2574 if (key->IsPropertyName()) { |
2582 VisitForAccumulatorValue(expr->obj()); | 2575 VisitForAccumulatorValue(expr->obj()); |
2583 ASSERT(a0.is(LoadIC::ReceiverRegister())); | 2576 __ Move(LoadIC::ReceiverRegister(), v0); |
2584 EmitNamedPropertyLoad(expr); | 2577 EmitNamedPropertyLoad(expr); |
2585 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2578 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2586 context()->Plug(v0); | 2579 context()->Plug(v0); |
2587 } else { | 2580 } else { |
2588 VisitForStackValue(expr->obj()); | 2581 VisitForStackValue(expr->obj()); |
2589 VisitForAccumulatorValue(expr->key()); | 2582 VisitForAccumulatorValue(expr->key()); |
2590 ASSERT(a0.is(KeyedLoadIC::NameRegister())); | 2583 __ Move(LoadIC::NameRegister(), v0); |
2591 ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); | 2584 __ pop(LoadIC::ReceiverRegister()); |
2592 __ pop(KeyedLoadIC::ReceiverRegister()); | |
2593 EmitKeyedPropertyLoad(expr); | 2585 EmitKeyedPropertyLoad(expr); |
2594 context()->Plug(v0); | 2586 context()->Plug(v0); |
2595 } | 2587 } |
2596 } | 2588 } |
2597 | 2589 |
2598 | 2590 |
2599 void FullCodeGenerator::CallIC(Handle<Code> code, | 2591 void FullCodeGenerator::CallIC(Handle<Code> code, |
2600 TypeFeedbackId id) { | 2592 TypeFeedbackId id) { |
2601 ic_total_count_++; | 2593 ic_total_count_++; |
2602 __ Call(code, RelocInfo::CODE_TARGET, id); | 2594 __ Call(code, RelocInfo::CODE_TARGET, id); |
(...skipping 13 matching lines...) Expand all Loading... |
2616 { StackValueContext context(this); | 2608 { StackValueContext context(this); |
2617 EmitVariableLoad(callee->AsVariableProxy()); | 2609 EmitVariableLoad(callee->AsVariableProxy()); |
2618 PrepareForBailout(callee, NO_REGISTERS); | 2610 PrepareForBailout(callee, NO_REGISTERS); |
2619 } | 2611 } |
2620 // Push undefined as receiver. This is patched in the method prologue if it | 2612 // Push undefined as receiver. This is patched in the method prologue if it |
2621 // is a sloppy mode method. | 2613 // is a sloppy mode method. |
2622 __ Push(isolate()->factory()->undefined_value()); | 2614 __ Push(isolate()->factory()->undefined_value()); |
2623 } else { | 2615 } else { |
2624 // Load the function from the receiver. | 2616 // Load the function from the receiver. |
2625 ASSERT(callee->IsProperty()); | 2617 ASSERT(callee->IsProperty()); |
2626 __ lw(v0, MemOperand(sp, 0)); | 2618 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
2627 EmitNamedPropertyLoad(callee->AsProperty()); | 2619 EmitNamedPropertyLoad(callee->AsProperty()); |
2628 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2620 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2629 // Push the target function under the receiver. | 2621 // Push the target function under the receiver. |
2630 __ lw(at, MemOperand(sp, 0)); | 2622 __ lw(at, MemOperand(sp, 0)); |
2631 __ push(at); | 2623 __ push(at); |
2632 __ sw(v0, MemOperand(sp, kPointerSize)); | 2624 __ sw(v0, MemOperand(sp, kPointerSize)); |
2633 } | 2625 } |
2634 | 2626 |
2635 EmitCall(expr, call_type); | 2627 EmitCall(expr, call_type); |
2636 } | 2628 } |
2637 | 2629 |
2638 | 2630 |
2639 // Code common for calls using the IC. | 2631 // Code common for calls using the IC. |
2640 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2632 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2641 Expression* key) { | 2633 Expression* key) { |
2642 // Load the key. | 2634 // Load the key. |
2643 VisitForAccumulatorValue(key); | 2635 VisitForAccumulatorValue(key); |
2644 ASSERT(a0.is(KeyedLoadIC::NameRegister())); | |
2645 | 2636 |
2646 Expression* callee = expr->expression(); | 2637 Expression* callee = expr->expression(); |
2647 | 2638 |
2648 // Load the function from the receiver. | 2639 // Load the function from the receiver. |
2649 ASSERT(callee->IsProperty()); | 2640 ASSERT(callee->IsProperty()); |
2650 __ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); | 2641 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
| 2642 __ Move(LoadIC::NameRegister(), v0); |
2651 EmitKeyedPropertyLoad(callee->AsProperty()); | 2643 EmitKeyedPropertyLoad(callee->AsProperty()); |
2652 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2644 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2653 | 2645 |
2654 // Push the target function under the receiver. | 2646 // Push the target function under the receiver. |
2655 __ lw(at, MemOperand(sp, 0)); | 2647 __ lw(at, MemOperand(sp, 0)); |
2656 __ push(at); | 2648 __ push(at); |
2657 __ sw(v0, MemOperand(sp, kPointerSize)); | 2649 __ sw(v0, MemOperand(sp, kPointerSize)); |
2658 | 2650 |
2659 EmitCall(expr, CallIC::METHOD); | 2651 EmitCall(expr, CallIC::METHOD); |
2660 } | 2652 } |
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4086 EmitInlineRuntimeCall(expr); | 4078 EmitInlineRuntimeCall(expr); |
4087 return; | 4079 return; |
4088 } | 4080 } |
4089 | 4081 |
4090 Comment cmnt(masm_, "[ CallRuntime"); | 4082 Comment cmnt(masm_, "[ CallRuntime"); |
4091 ZoneList<Expression*>* args = expr->arguments(); | 4083 ZoneList<Expression*>* args = expr->arguments(); |
4092 int arg_count = args->length(); | 4084 int arg_count = args->length(); |
4093 | 4085 |
4094 if (expr->is_jsruntime()) { | 4086 if (expr->is_jsruntime()) { |
4095 // Push the builtins object as the receiver. | 4087 // Push the builtins object as the receiver. |
4096 __ lw(a0, GlobalObjectOperand()); | 4088 Register receiver = LoadIC::ReceiverRegister(); |
4097 __ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset)); | 4089 __ lw(receiver, GlobalObjectOperand()); |
4098 __ push(a0); | 4090 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
| 4091 __ push(receiver); |
4099 | 4092 |
4100 // Load the function from the receiver. | 4093 // Load the function from the receiver. |
4101 ASSERT(a0.is(LoadIC::ReceiverRegister())); | |
4102 __ li(LoadIC::NameRegister(), Operand(expr->name())); | 4094 __ li(LoadIC::NameRegister(), Operand(expr->name())); |
4103 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4095 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
4104 | 4096 |
4105 // Push the target function under the receiver. | 4097 // Push the target function under the receiver. |
4106 __ lw(at, MemOperand(sp, 0)); | 4098 __ lw(at, MemOperand(sp, 0)); |
4107 __ push(at); | 4099 __ push(at); |
4108 __ sw(v0, MemOperand(sp, kPointerSize)); | 4100 __ sw(v0, MemOperand(sp, kPointerSize)); |
4109 | 4101 |
4110 // Push the arguments ("left-to-right"). | 4102 // Push the arguments ("left-to-right"). |
4111 int arg_count = args->length(); | 4103 int arg_count = args->length(); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4269 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 4261 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
4270 AccumulatorValueContext context(this); | 4262 AccumulatorValueContext context(this); |
4271 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4263 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4272 } else { | 4264 } else { |
4273 // Reserve space for result of postfix operation. | 4265 // Reserve space for result of postfix operation. |
4274 if (expr->is_postfix() && !context()->IsEffect()) { | 4266 if (expr->is_postfix() && !context()->IsEffect()) { |
4275 __ li(at, Operand(Smi::FromInt(0))); | 4267 __ li(at, Operand(Smi::FromInt(0))); |
4276 __ push(at); | 4268 __ push(at); |
4277 } | 4269 } |
4278 if (assign_type == NAMED_PROPERTY) { | 4270 if (assign_type == NAMED_PROPERTY) { |
4279 // Put the object both on the stack and in the accumulator. | 4271 // Put the object both on the stack and in the register. |
4280 VisitForAccumulatorValue(prop->obj()); | 4272 VisitForStackValue(prop->obj()); |
4281 __ push(v0); | 4273 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
4282 EmitNamedPropertyLoad(prop); | 4274 EmitNamedPropertyLoad(prop); |
4283 } else { | 4275 } else { |
4284 VisitForStackValue(prop->obj()); | 4276 VisitForStackValue(prop->obj()); |
4285 VisitForAccumulatorValue(prop->key()); | 4277 VisitForStackValue(prop->key()); |
4286 ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); | 4278 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize)); |
4287 __ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); | 4279 __ lw(LoadIC::NameRegister(), MemOperand(sp, 0)); |
4288 __ push(v0); | |
4289 EmitKeyedPropertyLoad(prop); | 4280 EmitKeyedPropertyLoad(prop); |
4290 } | 4281 } |
4291 } | 4282 } |
4292 | 4283 |
4293 // We need a second deoptimization point after loading the value | 4284 // We need a second deoptimization point after loading the value |
4294 // in case evaluating the property load my have a side effect. | 4285 // in case evaluating the property load my have a side effect. |
4295 if (assign_type == VARIABLE) { | 4286 if (assign_type == VARIABLE) { |
4296 PrepareForBailout(expr->expression(), TOS_REG); | 4287 PrepareForBailout(expr->expression(), TOS_REG); |
4297 } else { | 4288 } else { |
4298 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4289 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4868 Assembler::target_address_at(pc_immediate_load_address)) == | 4859 Assembler::target_address_at(pc_immediate_load_address)) == |
4869 reinterpret_cast<uint32_t>( | 4860 reinterpret_cast<uint32_t>( |
4870 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4861 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4871 return OSR_AFTER_STACK_CHECK; | 4862 return OSR_AFTER_STACK_CHECK; |
4872 } | 4863 } |
4873 | 4864 |
4874 | 4865 |
4875 } } // namespace v8::internal | 4866 } } // namespace v8::internal |
4876 | 4867 |
4877 #endif // V8_TARGET_ARCH_MIPS | 4868 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |