Chromium Code Reviews| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1330 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1330 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); |
| 1331 __ j(not_equal, slow); | 1331 __ j(not_equal, slow); |
| 1332 // Load next context in chain. | 1332 // Load next context in chain. |
| 1333 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1333 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
| 1334 __ jmp(&next); | 1334 __ jmp(&next); |
| 1335 __ bind(&fast); | 1335 __ bind(&fast); |
| 1336 } | 1336 } |
| 1337 | 1337 |
| 1338 // All extension objects were empty and it is safe to use a global | 1338 // All extension objects were empty and it is safe to use a global |
| 1339 // load IC call. | 1339 // load IC call. |
| 1340 __ mov(edx, GlobalObjectOperand()); | 1340 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 1341 __ mov(ecx, var->name()); | 1341 __ mov(LoadIC::NameRegister(), var->name()); |
| 1342 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1342 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1343 ? NOT_CONTEXTUAL | 1343 ? NOT_CONTEXTUAL |
| 1344 : CONTEXTUAL; | 1344 : CONTEXTUAL; |
| 1345 | 1345 |
| 1346 CallLoadIC(mode); | 1346 CallLoadIC(mode); |
| 1347 } | 1347 } |
| 1348 | 1348 |
| 1349 | 1349 |
| 1350 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1350 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1351 Label* slow) { | 1351 Label* slow) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1411 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1411 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1412 // Record position before possible IC call. | 1412 // Record position before possible IC call. |
| 1413 SetSourcePosition(proxy->position()); | 1413 SetSourcePosition(proxy->position()); |
| 1414 Variable* var = proxy->var(); | 1414 Variable* var = proxy->var(); |
| 1415 | 1415 |
| 1416 // Three cases: global variables, lookup variables, and all other types of | 1416 // Three cases: global variables, lookup variables, and all other types of |
| 1417 // variables. | 1417 // variables. |
| 1418 switch (var->location()) { | 1418 switch (var->location()) { |
| 1419 case Variable::UNALLOCATED: { | 1419 case Variable::UNALLOCATED: { |
| 1420 Comment cmnt(masm_, "[ Global variable"); | 1420 Comment cmnt(masm_, "[ Global variable"); |
| 1421 // Use inline caching. Variable name is passed in ecx and the global | 1421 // Use inline caching. Variable name is passed in ecx and the global |
|
Jakob Kummerow
2014/06/25 10:59:12
nit: outdated comment. I think you can just delete
mvstanton
2014/06/25 15:10:27
Done.
| |
| 1422 // object in eax. | 1422 // object in eax. |
| 1423 __ mov(edx, GlobalObjectOperand()); | 1423 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 1424 __ mov(ecx, var->name()); | 1424 __ mov(LoadIC::NameRegister(), var->name()); |
| 1425 CallLoadIC(CONTEXTUAL); | 1425 CallLoadIC(CONTEXTUAL); |
| 1426 context()->Plug(eax); | 1426 context()->Plug(eax); |
| 1427 break; | 1427 break; |
| 1428 } | 1428 } |
| 1429 | 1429 |
| 1430 case Variable::PARAMETER: | 1430 case Variable::PARAMETER: |
| 1431 case Variable::LOCAL: | 1431 case Variable::LOCAL: |
| 1432 case Variable::CONTEXT: { | 1432 case Variable::CONTEXT: { |
| 1433 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1433 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1434 : "[ Stack variable"); | 1434 : "[ Stack variable"); |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2004 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 2004 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
| 2005 __ mov(context_register(), | 2005 __ mov(context_register(), |
| 2006 Operand(ebp, StandardFrameConstants::kContextOffset)); | 2006 Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2007 __ pop(eax); // result | 2007 __ pop(eax); // result |
| 2008 EmitReturnSequence(); | 2008 EmitReturnSequence(); |
| 2009 __ bind(&l_resume); // received in eax | 2009 __ bind(&l_resume); // received in eax |
| 2010 __ PopTryHandler(); | 2010 __ PopTryHandler(); |
| 2011 | 2011 |
| 2012 // receiver = iter; f = iter.next; arg = received; | 2012 // receiver = iter; f = iter.next; arg = received; |
| 2013 __ bind(&l_next); | 2013 __ bind(&l_next); |
| 2014 __ mov(ecx, isolate()->factory()->next_string()); // "next" | 2014 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); |
| 2015 __ push(ecx); | 2015 Register keyedload_name = KeyedLoadIC::NameRegister(); |
| 2016 ASSERT(keyedload_receiver.is(edx)); | |
| 2017 ASSERT(keyedload_name.is(ecx)); | |
| 2018 | |
| 2019 __ mov(keyedload_name, | |
| 2020 isolate()->factory()->next_string()); // "next" | |
| 2021 __ push(keyedload_name); | |
| 2016 __ push(Operand(esp, 2 * kPointerSize)); // iter | 2022 __ push(Operand(esp, 2 * kPointerSize)); // iter |
| 2017 __ push(eax); // received | 2023 __ push(eax); // received |
| 2018 | 2024 |
| 2019 // result = receiver[f](arg); | 2025 // result = receiver[f](arg); |
| 2020 __ bind(&l_call); | 2026 __ bind(&l_call); |
| 2021 __ mov(edx, Operand(esp, kPointerSize)); | 2027 __ mov(keyedload_receiver, Operand(esp, kPointerSize)); |
| 2022 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2028 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2023 CallIC(ic, TypeFeedbackId::None()); | 2029 CallIC(ic, TypeFeedbackId::None()); |
| 2024 __ mov(edi, eax); | 2030 __ mov(edi, eax); |
| 2025 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2031 __ mov(Operand(esp, 2 * kPointerSize), edi); |
| 2026 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2032 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2027 __ CallStub(&stub); | 2033 __ CallStub(&stub); |
| 2028 | 2034 |
| 2029 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2035 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2030 __ Drop(1); // The function is still on the stack; drop it. | 2036 __ Drop(1); // The function is still on the stack; drop it. |
| 2031 | 2037 |
| 2032 // if (!result.done) goto l_try; | 2038 // if (!result.done) goto l_try; |
| 2033 __ bind(&l_loop); | 2039 __ bind(&l_loop); |
| 2034 __ push(eax); // save result | 2040 __ push(eax); // save result |
| 2035 __ mov(edx, eax); // result | 2041 Register load_receiver = LoadIC::ReceiverRegister(); |
| 2036 __ mov(ecx, isolate()->factory()->done_string()); // "done" | 2042 Register load_name = LoadIC::NameRegister(); |
| 2043 ASSERT(load_receiver.is(edx)); | |
| 2044 ASSERT(load_name.is(ecx)); | |
| 2045 __ mov(load_receiver, eax); // result | |
| 2046 __ mov(load_name, | |
| 2047 isolate()->factory()->done_string()); // "done" | |
| 2037 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax | 2048 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax |
| 2038 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2049 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2039 CallIC(bool_ic); | 2050 CallIC(bool_ic); |
| 2040 __ test(eax, eax); | 2051 __ test(eax, eax); |
| 2041 __ j(zero, &l_try); | 2052 __ j(zero, &l_try); |
| 2042 | 2053 |
| 2043 // result.value | 2054 // result.value |
| 2044 __ pop(edx); // result | 2055 __ pop(load_receiver); // result |
| 2045 __ mov(ecx, isolate()->factory()->value_string()); // "value" | 2056 __ mov(load_name, |
| 2057 isolate()->factory()->value_string()); // "value" | |
| 2046 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax | 2058 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax |
| 2047 context()->DropAndPlug(2, eax); // drop iter and g | 2059 context()->DropAndPlug(2, eax); // drop iter and g |
| 2048 break; | 2060 break; |
| 2049 } | 2061 } |
| 2050 } | 2062 } |
| 2051 } | 2063 } |
| 2052 | 2064 |
| 2053 | 2065 |
| 2054 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2066 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2055 Expression *value, | 2067 Expression *value, |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2195 // root set. | 2207 // root set. |
| 2196 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, | 2208 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
| 2197 ecx, edx, kDontSaveFPRegs); | 2209 ecx, edx, kDontSaveFPRegs); |
| 2198 } | 2210 } |
| 2199 | 2211 |
| 2200 | 2212 |
| 2201 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2213 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2202 SetSourcePosition(prop->position()); | 2214 SetSourcePosition(prop->position()); |
| 2203 Literal* key = prop->key()->AsLiteral(); | 2215 Literal* key = prop->key()->AsLiteral(); |
| 2204 ASSERT(!key->value()->IsSmi()); | 2216 ASSERT(!key->value()->IsSmi()); |
| 2205 __ mov(ecx, Immediate(key->value())); | 2217 __ mov(LoadIC::NameRegister(), Immediate(key->value())); |
| 2206 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2218 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2207 } | 2219 } |
| 2208 | 2220 |
| 2209 | 2221 |
| 2210 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2222 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2211 SetSourcePosition(prop->position()); | 2223 SetSourcePosition(prop->position()); |
| 2212 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2224 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2213 CallIC(ic, prop->PropertyFeedbackId()); | 2225 CallIC(ic, prop->PropertyFeedbackId()); |
| 2214 } | 2226 } |
| 2215 | 2227 |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2493 context()->Plug(eax); | 2505 context()->Plug(eax); |
| 2494 } | 2506 } |
| 2495 | 2507 |
| 2496 | 2508 |
| 2497 void FullCodeGenerator::VisitProperty(Property* expr) { | 2509 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2498 Comment cmnt(masm_, "[ Property"); | 2510 Comment cmnt(masm_, "[ Property"); |
| 2499 Expression* key = expr->key(); | 2511 Expression* key = expr->key(); |
| 2500 | 2512 |
| 2501 if (key->IsPropertyName()) { | 2513 if (key->IsPropertyName()) { |
| 2502 VisitForAccumulatorValue(expr->obj()); | 2514 VisitForAccumulatorValue(expr->obj()); |
| 2503 __ mov(edx, result_register()); | 2515 __ mov(LoadIC::ReceiverRegister(), result_register()); |
| 2504 EmitNamedPropertyLoad(expr); | 2516 EmitNamedPropertyLoad(expr); |
| 2505 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2517 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2506 context()->Plug(eax); | 2518 context()->Plug(eax); |
| 2507 } else { | 2519 } else { |
| 2508 VisitForStackValue(expr->obj()); | 2520 VisitForStackValue(expr->obj()); |
| 2509 VisitForAccumulatorValue(expr->key()); | 2521 VisitForAccumulatorValue(expr->key()); |
| 2510 __ pop(edx); // Object. | 2522 __ pop(KeyedLoadIC::ReceiverRegister()); // Object. |
| 2511 __ mov(ecx, result_register()); // Key. | 2523 __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. |
| 2512 EmitKeyedPropertyLoad(expr); | 2524 EmitKeyedPropertyLoad(expr); |
| 2513 context()->Plug(eax); | 2525 context()->Plug(eax); |
| 2514 } | 2526 } |
| 2515 } | 2527 } |
| 2516 | 2528 |
| 2517 | 2529 |
| 2518 void FullCodeGenerator::CallIC(Handle<Code> code, | 2530 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2519 TypeFeedbackId ast_id) { | 2531 TypeFeedbackId ast_id) { |
| 2520 ic_total_count_++; | 2532 ic_total_count_++; |
| 2521 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2533 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2534 { StackValueContext context(this); | 2546 { StackValueContext context(this); |
| 2535 EmitVariableLoad(callee->AsVariableProxy()); | 2547 EmitVariableLoad(callee->AsVariableProxy()); |
| 2536 PrepareForBailout(callee, NO_REGISTERS); | 2548 PrepareForBailout(callee, NO_REGISTERS); |
| 2537 } | 2549 } |
| 2538 // Push undefined as receiver. This is patched in the method prologue if it | 2550 // Push undefined as receiver. This is patched in the method prologue if it |
| 2539 // is a sloppy mode method. | 2551 // is a sloppy mode method. |
| 2540 __ push(Immediate(isolate()->factory()->undefined_value())); | 2552 __ push(Immediate(isolate()->factory()->undefined_value())); |
| 2541 } else { | 2553 } else { |
| 2542 // Load the function from the receiver. | 2554 // Load the function from the receiver. |
| 2543 ASSERT(callee->IsProperty()); | 2555 ASSERT(callee->IsProperty()); |
| 2544 __ mov(edx, Operand(esp, 0)); | 2556 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); |
| 2545 EmitNamedPropertyLoad(callee->AsProperty()); | 2557 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2546 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2558 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2547 // Push the target function under the receiver. | 2559 // Push the target function under the receiver. |
| 2548 __ push(Operand(esp, 0)); | 2560 __ push(Operand(esp, 0)); |
| 2549 __ mov(Operand(esp, kPointerSize), eax); | 2561 __ mov(Operand(esp, kPointerSize), eax); |
| 2550 } | 2562 } |
| 2551 | 2563 |
| 2552 EmitCall(expr, call_type); | 2564 EmitCall(expr, call_type); |
| 2553 } | 2565 } |
| 2554 | 2566 |
| 2555 | 2567 |
| 2556 // Code common for calls using the IC. | 2568 // Code common for calls using the IC. |
| 2557 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2569 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 2558 Expression* key) { | 2570 Expression* key) { |
| 2559 // Load the key. | 2571 // Load the key. |
| 2560 VisitForAccumulatorValue(key); | 2572 VisitForAccumulatorValue(key); |
| 2561 | 2573 |
| 2562 Expression* callee = expr->expression(); | 2574 Expression* callee = expr->expression(); |
| 2563 | 2575 |
| 2564 // Load the function from the receiver. | 2576 // Load the function from the receiver. |
| 2565 ASSERT(callee->IsProperty()); | 2577 ASSERT(callee->IsProperty()); |
| 2566 __ mov(edx, Operand(esp, 0)); | 2578 __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); |
| 2567 // Move the key into the right register for the keyed load IC. | 2579 // Move the key into the right register for the keyed load IC. |
| 2568 __ mov(ecx, eax); | 2580 __ mov(KeyedLoadIC::NameRegister(), eax); |
| 2569 EmitKeyedPropertyLoad(callee->AsProperty()); | 2581 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2570 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2582 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2571 | 2583 |
| 2572 // Push the target function under the receiver. | 2584 // Push the target function under the receiver. |
| 2573 __ push(Operand(esp, 0)); | 2585 __ push(Operand(esp, 0)); |
| 2574 __ mov(Operand(esp, kPointerSize), eax); | 2586 __ mov(Operand(esp, kPointerSize), eax); |
| 2575 | 2587 |
| 2576 EmitCall(expr, CallIC::METHOD); | 2588 EmitCall(expr, CallIC::METHOD); |
| 2577 } | 2589 } |
| 2578 | 2590 |
| (...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4016 | 4028 |
| 4017 Comment cmnt(masm_, "[ CallRuntime"); | 4029 Comment cmnt(masm_, "[ CallRuntime"); |
| 4018 ZoneList<Expression*>* args = expr->arguments(); | 4030 ZoneList<Expression*>* args = expr->arguments(); |
| 4019 | 4031 |
| 4020 if (expr->is_jsruntime()) { | 4032 if (expr->is_jsruntime()) { |
| 4021 // Push the builtins object as receiver. | 4033 // Push the builtins object as receiver. |
| 4022 __ mov(eax, GlobalObjectOperand()); | 4034 __ mov(eax, GlobalObjectOperand()); |
| 4023 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4035 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
| 4024 | 4036 |
| 4025 // Load the function from the receiver. | 4037 // Load the function from the receiver. |
| 4026 __ mov(edx, Operand(esp, 0)); | 4038 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); |
| 4027 __ mov(ecx, Immediate(expr->name())); | 4039 __ mov(LoadIC::NameRegister(), Immediate(expr->name())); |
| 4028 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4040 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4029 | 4041 |
| 4030 // Push the target function under the receiver. | 4042 // Push the target function under the receiver. |
| 4031 __ push(Operand(esp, 0)); | 4043 __ push(Operand(esp, 0)); |
| 4032 __ mov(Operand(esp, kPointerSize), eax); | 4044 __ mov(Operand(esp, kPointerSize), eax); |
| 4033 | 4045 |
| 4034 // Code common for calls using the IC. | 4046 // Code common for calls using the IC. |
| 4035 ZoneList<Expression*>* args = expr->arguments(); | 4047 ZoneList<Expression*>* args = expr->arguments(); |
| 4036 int arg_count = args->length(); | 4048 int arg_count = args->length(); |
| 4037 for (int i = 0; i < arg_count; i++) { | 4049 for (int i = 0; i < arg_count; i++) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4200 AccumulatorValueContext context(this); | 4212 AccumulatorValueContext context(this); |
| 4201 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4213 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4202 } else { | 4214 } else { |
| 4203 // Reserve space for result of postfix operation. | 4215 // Reserve space for result of postfix operation. |
| 4204 if (expr->is_postfix() && !context()->IsEffect()) { | 4216 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4205 __ push(Immediate(Smi::FromInt(0))); | 4217 __ push(Immediate(Smi::FromInt(0))); |
| 4206 } | 4218 } |
| 4207 if (assign_type == NAMED_PROPERTY) { | 4219 if (assign_type == NAMED_PROPERTY) { |
| 4208 // Put the object both on the stack and in edx. | 4220 // Put the object both on the stack and in edx. |
| 4209 VisitForAccumulatorValue(prop->obj()); | 4221 VisitForAccumulatorValue(prop->obj()); |
| 4222 ASSERT(!eax.is(LoadIC::ReceiverRegister())); | |
| 4210 __ push(eax); | 4223 __ push(eax); |
| 4211 __ mov(edx, eax); | 4224 __ mov(LoadIC::ReceiverRegister(), eax); |
| 4212 EmitNamedPropertyLoad(prop); | 4225 EmitNamedPropertyLoad(prop); |
| 4213 } else { | 4226 } else { |
| 4214 VisitForStackValue(prop->obj()); | 4227 VisitForStackValue(prop->obj()); |
| 4215 VisitForStackValue(prop->key()); | 4228 VisitForStackValue(prop->key()); |
| 4216 __ mov(edx, Operand(esp, kPointerSize)); // Object. | 4229 __ mov(KeyedLoadIC::ReceiverRegister(), |
| 4217 __ mov(ecx, Operand(esp, 0)); // Key. | 4230 Operand(esp, kPointerSize)); // Object. |
| 4231 __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. | |
| 4218 EmitKeyedPropertyLoad(prop); | 4232 EmitKeyedPropertyLoad(prop); |
| 4219 } | 4233 } |
| 4220 } | 4234 } |
| 4221 | 4235 |
| 4222 // We need a second deoptimization point after loading the value | 4236 // We need a second deoptimization point after loading the value |
| 4223 // in case evaluating the property load my have a side effect. | 4237 // in case evaluating the property load my have a side effect. |
| 4224 if (assign_type == VARIABLE) { | 4238 if (assign_type == VARIABLE) { |
| 4225 PrepareForBailout(expr->expression(), TOS_REG); | 4239 PrepareForBailout(expr->expression(), TOS_REG); |
| 4226 } else { | 4240 } else { |
| 4227 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4241 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4364 } | 4378 } |
| 4365 | 4379 |
| 4366 | 4380 |
| 4367 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4381 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4368 VariableProxy* proxy = expr->AsVariableProxy(); | 4382 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4369 ASSERT(!context()->IsEffect()); | 4383 ASSERT(!context()->IsEffect()); |
| 4370 ASSERT(!context()->IsTest()); | 4384 ASSERT(!context()->IsTest()); |
| 4371 | 4385 |
| 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 __ mov(edx, GlobalObjectOperand()); | 4388 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 4375 __ mov(ecx, Immediate(proxy->name())); | 4389 __ mov(LoadIC::NameRegister(), Immediate(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(eax); | 4394 context()->Plug(eax); |
| 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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4799 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4813 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4800 Assembler::target_address_at(call_target_address, | 4814 Assembler::target_address_at(call_target_address, |
| 4801 unoptimized_code)); | 4815 unoptimized_code)); |
| 4802 return OSR_AFTER_STACK_CHECK; | 4816 return OSR_AFTER_STACK_CHECK; |
| 4803 } | 4817 } |
| 4804 | 4818 |
| 4805 | 4819 |
| 4806 } } // namespace v8::internal | 4820 } } // namespace v8::internal |
| 4807 | 4821 |
| 4808 #endif // V8_TARGET_ARCH_IA32 | 4822 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |