| 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-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 // Check that extension is NULL. | 1382 // Check that extension is NULL. |
| 1383 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1383 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
| 1384 __ tst(temp, temp); | 1384 __ tst(temp, temp); |
| 1385 __ b(ne, slow); | 1385 __ b(ne, slow); |
| 1386 // Load next context in chain. | 1386 // Load next context in chain. |
| 1387 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1387 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
| 1388 __ b(&loop); | 1388 __ b(&loop); |
| 1389 __ bind(&fast); | 1389 __ bind(&fast); |
| 1390 } | 1390 } |
| 1391 | 1391 |
| 1392 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 1392 __ ldr(r0, GlobalObjectOperand()); |
| 1393 __ mov(LoadIC::NameRegister(), Operand(var->name())); | 1393 __ mov(r2, Operand(var->name())); |
| 1394 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1394 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1395 ? NOT_CONTEXTUAL | 1395 ? NOT_CONTEXTUAL |
| 1396 : CONTEXTUAL; | 1396 : CONTEXTUAL; |
| 1397 CallLoadIC(mode); | 1397 CallLoadIC(mode); |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 | 1400 |
| 1401 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1401 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1402 Label* slow) { | 1402 Label* slow) { |
| 1403 ASSERT(var->IsContextSlot()); | 1403 ASSERT(var->IsContextSlot()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1466 // Record position before possible IC call. | 1466 // Record position before possible IC call. |
| 1467 SetSourcePosition(proxy->position()); | 1467 SetSourcePosition(proxy->position()); |
| 1468 Variable* var = proxy->var(); | 1468 Variable* var = proxy->var(); |
| 1469 | 1469 |
| 1470 // Three cases: global variables, lookup variables, and all other types of | 1470 // Three cases: global variables, lookup variables, and all other types of |
| 1471 // variables. | 1471 // variables. |
| 1472 switch (var->location()) { | 1472 switch (var->location()) { |
| 1473 case Variable::UNALLOCATED: { | 1473 case Variable::UNALLOCATED: { |
| 1474 Comment cmnt(masm_, "[ Global variable"); | 1474 Comment cmnt(masm_, "[ Global variable"); |
| 1475 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 1475 // Use inline caching. Variable name is passed in r2 and the global |
| 1476 __ mov(LoadIC::NameRegister(), Operand(var->name())); | 1476 // object (receiver) in r0. |
| 1477 __ ldr(r0, GlobalObjectOperand()); |
| 1478 __ mov(r2, Operand(var->name())); |
| 1477 CallLoadIC(CONTEXTUAL); | 1479 CallLoadIC(CONTEXTUAL); |
| 1478 context()->Plug(r0); | 1480 context()->Plug(r0); |
| 1479 break; | 1481 break; |
| 1480 } | 1482 } |
| 1481 | 1483 |
| 1482 case Variable::PARAMETER: | 1484 case Variable::PARAMETER: |
| 1483 case Variable::LOCAL: | 1485 case Variable::LOCAL: |
| 1484 case Variable::CONTEXT: { | 1486 case Variable::CONTEXT: { |
| 1485 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1487 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1486 : "[ Stack variable"); | 1488 : "[ Stack variable"); |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2044 kLRHasBeenSaved, kDontSaveFPRegs); | 2046 kLRHasBeenSaved, kDontSaveFPRegs); |
| 2045 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2047 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 2046 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2048 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2047 __ pop(r0); // result | 2049 __ pop(r0); // result |
| 2048 EmitReturnSequence(); | 2050 EmitReturnSequence(); |
| 2049 __ bind(&l_resume); // received in r0 | 2051 __ bind(&l_resume); // received in r0 |
| 2050 __ PopTryHandler(); | 2052 __ PopTryHandler(); |
| 2051 | 2053 |
| 2052 // receiver = iter; f = 'next'; arg = received; | 2054 // receiver = iter; f = 'next'; arg = received; |
| 2053 __ bind(&l_next); | 2055 __ bind(&l_next); |
| 2054 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); | |
| 2055 Register keyedload_name = KeyedLoadIC::NameRegister(); | |
| 2056 ASSERT(keyedload_receiver.is(r1)); | |
| 2057 ASSERT(keyedload_name.is(r0)); | |
| 2058 | |
| 2059 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" | 2056 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" |
| 2060 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2057 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
| 2061 __ Push(r2, r3, r0); // "next", iter, received | 2058 __ Push(r2, r3, r0); // "next", iter, received |
| 2062 | 2059 |
| 2063 // result = receiver[f](arg); | 2060 // result = receiver[f](arg); |
| 2064 __ bind(&l_call); | 2061 __ bind(&l_call); |
| 2065 __ ldr(keyedload_receiver, MemOperand(sp, kPointerSize)); | 2062 __ ldr(r1, MemOperand(sp, kPointerSize)); |
| 2066 __ ldr(keyedload_name, MemOperand(sp, 2 * kPointerSize)); | 2063 __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); |
| 2067 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2064 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2068 CallIC(ic, TypeFeedbackId::None()); | 2065 CallIC(ic, TypeFeedbackId::None()); |
| 2069 __ mov(r1, r0); | 2066 __ mov(r1, r0); |
| 2070 __ str(r1, MemOperand(sp, 2 * kPointerSize)); | 2067 __ str(r1, MemOperand(sp, 2 * kPointerSize)); |
| 2071 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2068 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2072 __ CallStub(&stub); | 2069 __ CallStub(&stub); |
| 2073 | 2070 |
| 2074 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2071 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2075 __ Drop(1); // The function is still on the stack; drop it. | 2072 __ Drop(1); // The function is still on the stack; drop it. |
| 2076 | 2073 |
| 2077 // if (!result.done) goto l_try; | 2074 // if (!result.done) goto l_try; |
| 2078 __ bind(&l_loop); | 2075 __ bind(&l_loop); |
| 2079 Register load_receiver = LoadIC::ReceiverRegister(); | 2076 __ push(r0); // save result |
| 2080 Register load_name = LoadIC::NameRegister(); | 2077 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" |
| 2081 ASSERT(load_receiver.is(r0)); | 2078 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 |
| 2082 ASSERT(load_name.is(r2)); | |
| 2083 | |
| 2084 __ push(load_receiver); // save result | |
| 2085 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | |
| 2086 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done | |
| 2087 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2079 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2088 CallIC(bool_ic); | 2080 CallIC(bool_ic); |
| 2089 __ cmp(r0, Operand(0)); | 2081 __ cmp(r0, Operand(0)); |
| 2090 __ b(eq, &l_try); | 2082 __ b(eq, &l_try); |
| 2091 | 2083 |
| 2092 // result.value | 2084 // result.value |
| 2093 __ pop(load_receiver); // result | 2085 __ pop(r0); // result |
| 2094 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 2086 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" |
| 2095 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value | 2087 CallLoadIC(NOT_CONTEXTUAL); // result.value in r0 |
| 2096 context()->DropAndPlug(2, r0); // drop iter and g | 2088 context()->DropAndPlug(2, r0); // drop iter and g |
| 2097 break; | 2089 break; |
| 2098 } | 2090 } |
| 2099 } | 2091 } |
| 2100 } | 2092 } |
| 2101 | 2093 |
| 2102 | 2094 |
| 2103 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2095 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2104 Expression *value, | 2096 Expression *value, |
| 2105 JSGeneratorObject::ResumeMode resume_mode) { | 2097 JSGeneratorObject::ResumeMode resume_mode) { |
| 2106 // The value stays in r0, and is ultimately read by the resumed generator, as | 2098 // The value stays in r0, and is ultimately read by the resumed generator, as |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2259 // Only the value field needs a write barrier, as the other values are in the | 2251 // Only the value field needs a write barrier, as the other values are in the |
| 2260 // root set. | 2252 // root set. |
| 2261 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, | 2253 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, |
| 2262 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 2254 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2263 } | 2255 } |
| 2264 | 2256 |
| 2265 | 2257 |
| 2266 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2258 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2267 SetSourcePosition(prop->position()); | 2259 SetSourcePosition(prop->position()); |
| 2268 Literal* key = prop->key()->AsLiteral(); | 2260 Literal* key = prop->key()->AsLiteral(); |
| 2269 __ mov(LoadIC::NameRegister(), Operand(key->value())); | 2261 __ mov(r2, Operand(key->value())); |
| 2270 // Call load IC. It has register arguments receiver and property. | 2262 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 2271 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2263 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2272 } | 2264 } |
| 2273 | 2265 |
| 2274 | 2266 |
| 2275 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2267 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2276 SetSourcePosition(prop->position()); | 2268 SetSourcePosition(prop->position()); |
| 2277 // Call keyed load IC. It has register arguments receiver and key. | 2269 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 2278 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2270 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2279 CallIC(ic, prop->PropertyFeedbackId()); | 2271 CallIC(ic, prop->PropertyFeedbackId()); |
| 2280 } | 2272 } |
| 2281 | 2273 |
| 2282 | 2274 |
| 2283 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2275 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2284 Token::Value op, | 2276 Token::Value op, |
| 2285 OverwriteMode mode, | 2277 OverwriteMode mode, |
| 2286 Expression* left_expr, | 2278 Expression* left_expr, |
| 2287 Expression* right_expr) { | 2279 Expression* right_expr) { |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2556 context()->Plug(r0); | 2548 context()->Plug(r0); |
| 2557 } | 2549 } |
| 2558 | 2550 |
| 2559 | 2551 |
| 2560 void FullCodeGenerator::VisitProperty(Property* expr) { | 2552 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2561 Comment cmnt(masm_, "[ Property"); | 2553 Comment cmnt(masm_, "[ Property"); |
| 2562 Expression* key = expr->key(); | 2554 Expression* key = expr->key(); |
| 2563 | 2555 |
| 2564 if (key->IsPropertyName()) { | 2556 if (key->IsPropertyName()) { |
| 2565 VisitForAccumulatorValue(expr->obj()); | 2557 VisitForAccumulatorValue(expr->obj()); |
| 2566 ASSERT(r0.is(LoadIC::ReceiverRegister())); | |
| 2567 EmitNamedPropertyLoad(expr); | 2558 EmitNamedPropertyLoad(expr); |
| 2568 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2559 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2569 context()->Plug(r0); | 2560 context()->Plug(r0); |
| 2570 } else { | 2561 } else { |
| 2571 VisitForStackValue(expr->obj()); | 2562 VisitForStackValue(expr->obj()); |
| 2572 VisitForAccumulatorValue(expr->key()); | 2563 VisitForAccumulatorValue(expr->key()); |
| 2573 ASSERT(r0.is(KeyedLoadIC::NameRegister())); | 2564 __ pop(r1); |
| 2574 __ pop(KeyedLoadIC::ReceiverRegister()); | |
| 2575 EmitKeyedPropertyLoad(expr); | 2565 EmitKeyedPropertyLoad(expr); |
| 2576 context()->Plug(r0); | 2566 context()->Plug(r0); |
| 2577 } | 2567 } |
| 2578 } | 2568 } |
| 2579 | 2569 |
| 2580 | 2570 |
| 2581 void FullCodeGenerator::CallIC(Handle<Code> code, | 2571 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2582 TypeFeedbackId ast_id) { | 2572 TypeFeedbackId ast_id) { |
| 2583 ic_total_count_++; | 2573 ic_total_count_++; |
| 2584 // All calls must have a predictable size in full-codegen code to ensure that | 2574 // All calls must have a predictable size in full-codegen code to ensure that |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2601 { StackValueContext context(this); | 2591 { StackValueContext context(this); |
| 2602 EmitVariableLoad(callee->AsVariableProxy()); | 2592 EmitVariableLoad(callee->AsVariableProxy()); |
| 2603 PrepareForBailout(callee, NO_REGISTERS); | 2593 PrepareForBailout(callee, NO_REGISTERS); |
| 2604 } | 2594 } |
| 2605 // Push undefined as receiver. This is patched in the method prologue if it | 2595 // Push undefined as receiver. This is patched in the method prologue if it |
| 2606 // is a sloppy mode method. | 2596 // is a sloppy mode method. |
| 2607 __ Push(isolate()->factory()->undefined_value()); | 2597 __ Push(isolate()->factory()->undefined_value()); |
| 2608 } else { | 2598 } else { |
| 2609 // Load the function from the receiver. | 2599 // Load the function from the receiver. |
| 2610 ASSERT(callee->IsProperty()); | 2600 ASSERT(callee->IsProperty()); |
| 2611 __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); | 2601 __ ldr(r0, MemOperand(sp, 0)); |
| 2612 EmitNamedPropertyLoad(callee->AsProperty()); | 2602 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2613 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2603 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2614 // Push the target function under the receiver. | 2604 // Push the target function under the receiver. |
| 2615 __ ldr(ip, MemOperand(sp, 0)); | 2605 __ ldr(ip, MemOperand(sp, 0)); |
| 2616 __ push(ip); | 2606 __ push(ip); |
| 2617 __ str(r0, MemOperand(sp, kPointerSize)); | 2607 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2618 } | 2608 } |
| 2619 | 2609 |
| 2620 EmitCall(expr, call_type); | 2610 EmitCall(expr, call_type); |
| 2621 } | 2611 } |
| 2622 | 2612 |
| 2623 | 2613 |
| 2624 // Code common for calls using the IC. | 2614 // Code common for calls using the IC. |
| 2625 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2615 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 2626 Expression* key) { | 2616 Expression* key) { |
| 2627 // Load the key. | 2617 // Load the key. |
| 2628 VisitForAccumulatorValue(key); | 2618 VisitForAccumulatorValue(key); |
| 2629 ASSERT(r0.is(KeyedLoadIC::NameRegister())); | |
| 2630 | 2619 |
| 2631 Expression* callee = expr->expression(); | 2620 Expression* callee = expr->expression(); |
| 2632 | 2621 |
| 2633 // Load the function from the receiver. | 2622 // Load the function from the receiver. |
| 2634 ASSERT(callee->IsProperty()); | 2623 ASSERT(callee->IsProperty()); |
| 2635 __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); | 2624 __ ldr(r1, MemOperand(sp, 0)); |
| 2636 EmitKeyedPropertyLoad(callee->AsProperty()); | 2625 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2637 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2626 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2638 | 2627 |
| 2639 // Push the target function under the receiver. | 2628 // Push the target function under the receiver. |
| 2640 __ ldr(ip, MemOperand(sp, 0)); | 2629 __ ldr(ip, MemOperand(sp, 0)); |
| 2641 __ push(ip); | 2630 __ push(ip); |
| 2642 __ str(r0, MemOperand(sp, kPointerSize)); | 2631 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2643 | 2632 |
| 2644 EmitCall(expr, CallIC::METHOD); | 2633 EmitCall(expr, CallIC::METHOD); |
| 2645 } | 2634 } |
| (...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4043 ZoneList<Expression*>* args = expr->arguments(); | 4032 ZoneList<Expression*>* args = expr->arguments(); |
| 4044 int arg_count = args->length(); | 4033 int arg_count = args->length(); |
| 4045 | 4034 |
| 4046 if (expr->is_jsruntime()) { | 4035 if (expr->is_jsruntime()) { |
| 4047 // Push the builtins object as the receiver. | 4036 // Push the builtins object as the receiver. |
| 4048 __ ldr(r0, GlobalObjectOperand()); | 4037 __ ldr(r0, GlobalObjectOperand()); |
| 4049 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); | 4038 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); |
| 4050 __ push(r0); | 4039 __ push(r0); |
| 4051 | 4040 |
| 4052 // Load the function from the receiver. | 4041 // Load the function from the receiver. |
| 4053 ASSERT(r0.is(LoadIC::ReceiverRegister())); | 4042 __ mov(r2, Operand(expr->name())); |
| 4054 __ mov(LoadIC::NameRegister(), Operand(expr->name())); | |
| 4055 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4043 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4056 | 4044 |
| 4057 // Push the target function under the receiver. | 4045 // Push the target function under the receiver. |
| 4058 __ ldr(ip, MemOperand(sp, 0)); | 4046 __ ldr(ip, MemOperand(sp, 0)); |
| 4059 __ push(ip); | 4047 __ push(ip); |
| 4060 __ str(r0, MemOperand(sp, kPointerSize)); | 4048 __ str(r0, MemOperand(sp, kPointerSize)); |
| 4061 | 4049 |
| 4062 // Push the arguments ("left-to-right"). | 4050 // Push the arguments ("left-to-right"). |
| 4063 int arg_count = args->length(); | 4051 int arg_count = args->length(); |
| 4064 for (int i = 0; i < arg_count; i++) { | 4052 for (int i = 0; i < arg_count; i++) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4223 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4211 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4224 } else { | 4212 } else { |
| 4225 // Reserve space for result of postfix operation. | 4213 // Reserve space for result of postfix operation. |
| 4226 if (expr->is_postfix() && !context()->IsEffect()) { | 4214 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4227 __ mov(ip, Operand(Smi::FromInt(0))); | 4215 __ mov(ip, Operand(Smi::FromInt(0))); |
| 4228 __ push(ip); | 4216 __ push(ip); |
| 4229 } | 4217 } |
| 4230 if (assign_type == NAMED_PROPERTY) { | 4218 if (assign_type == NAMED_PROPERTY) { |
| 4231 // Put the object both on the stack and in the accumulator. | 4219 // Put the object both on the stack and in the accumulator. |
| 4232 VisitForAccumulatorValue(prop->obj()); | 4220 VisitForAccumulatorValue(prop->obj()); |
| 4233 ASSERT(r0.is(LoadIC::ReceiverRegister())); | 4221 __ push(r0); |
| 4234 __ push(LoadIC::ReceiverRegister()); | |
| 4235 EmitNamedPropertyLoad(prop); | 4222 EmitNamedPropertyLoad(prop); |
| 4236 } else { | 4223 } else { |
| 4237 VisitForStackValue(prop->obj()); | 4224 VisitForStackValue(prop->obj()); |
| 4238 VisitForAccumulatorValue(prop->key()); | 4225 VisitForAccumulatorValue(prop->key()); |
| 4239 ASSERT(r0.is(KeyedLoadIC::NameRegister())); | 4226 __ ldr(r1, MemOperand(sp, 0)); |
| 4240 __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); | 4227 __ push(r0); |
| 4241 __ push(KeyedLoadIC::NameRegister()); | |
| 4242 EmitKeyedPropertyLoad(prop); | 4228 EmitKeyedPropertyLoad(prop); |
| 4243 } | 4229 } |
| 4244 } | 4230 } |
| 4245 | 4231 |
| 4246 // We need a second deoptimization point after loading the value | 4232 // We need a second deoptimization point after loading the value |
| 4247 // in case evaluating the property load my have a side effect. | 4233 // in case evaluating the property load my have a side effect. |
| 4248 if (assign_type == VARIABLE) { | 4234 if (assign_type == VARIABLE) { |
| 4249 PrepareForBailout(expr->expression(), TOS_REG); | 4235 PrepareForBailout(expr->expression(), TOS_REG); |
| 4250 } else { | 4236 } else { |
| 4251 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4237 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4378 } | 4364 } |
| 4379 } | 4365 } |
| 4380 | 4366 |
| 4381 | 4367 |
| 4382 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4368 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4383 ASSERT(!context()->IsEffect()); | 4369 ASSERT(!context()->IsEffect()); |
| 4384 ASSERT(!context()->IsTest()); | 4370 ASSERT(!context()->IsTest()); |
| 4385 VariableProxy* proxy = expr->AsVariableProxy(); | 4371 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4386 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4372 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4387 Comment cmnt(masm_, "[ Global variable"); | 4373 Comment cmnt(masm_, "[ Global variable"); |
| 4388 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 4374 __ ldr(r0, GlobalObjectOperand()); |
| 4389 __ mov(LoadIC::NameRegister(), Operand(proxy->name())); | 4375 __ mov(r2, Operand(proxy->name())); |
| 4390 // Use a regular load, not a contextual load, to avoid a reference | 4376 // Use a regular load, not a contextual load, to avoid a reference |
| 4391 // error. | 4377 // error. |
| 4392 CallLoadIC(NOT_CONTEXTUAL); | 4378 CallLoadIC(NOT_CONTEXTUAL); |
| 4393 PrepareForBailout(expr, TOS_REG); | 4379 PrepareForBailout(expr, TOS_REG); |
| 4394 context()->Plug(r0); | 4380 context()->Plug(r0); |
| 4395 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4381 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4396 Comment cmnt(masm_, "[ Lookup slot"); | 4382 Comment cmnt(masm_, "[ Lookup slot"); |
| 4397 Label done, slow; | 4383 Label done, slow; |
| 4398 | 4384 |
| 4399 // Generate code for loading from variables potentially shadowed | 4385 // Generate code for loading from variables potentially shadowed |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4835 | 4821 |
| 4836 ASSERT(interrupt_address == | 4822 ASSERT(interrupt_address == |
| 4837 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4823 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4838 return OSR_AFTER_STACK_CHECK; | 4824 return OSR_AFTER_STACK_CHECK; |
| 4839 } | 4825 } |
| 4840 | 4826 |
| 4841 | 4827 |
| 4842 } } // namespace v8::internal | 4828 } } // namespace v8::internal |
| 4843 | 4829 |
| 4844 #endif // V8_TARGET_ARCH_ARM | 4830 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |