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