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