| 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 1793 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1804         : KEYED_PROPERTY; | 1804         : KEYED_PROPERTY; | 
| 1805   } | 1805   } | 
| 1806 | 1806 | 
| 1807   // Evaluate LHS expression. | 1807   // Evaluate LHS expression. | 
| 1808   switch (assign_type) { | 1808   switch (assign_type) { | 
| 1809     case VARIABLE: | 1809     case VARIABLE: | 
| 1810       // Nothing to do here. | 1810       // Nothing to do here. | 
| 1811       break; | 1811       break; | 
| 1812     case NAMED_PROPERTY: | 1812     case NAMED_PROPERTY: | 
| 1813       if (expr->is_compound()) { | 1813       if (expr->is_compound()) { | 
| 1814         // We need the receiver both on the stack and in edx. | 1814         // We need the receiver both on the stack and in the register. | 
| 1815         VisitForStackValue(property->obj()); | 1815         VisitForStackValue(property->obj()); | 
| 1816         __ mov(edx, Operand(esp, 0)); | 1816         __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); | 
| 1817       } else { | 1817       } else { | 
| 1818         VisitForStackValue(property->obj()); | 1818         VisitForStackValue(property->obj()); | 
| 1819       } | 1819       } | 
| 1820       break; | 1820       break; | 
| 1821     case KEYED_PROPERTY: { | 1821     case KEYED_PROPERTY: { | 
| 1822       if (expr->is_compound()) { | 1822       if (expr->is_compound()) { | 
| 1823         VisitForStackValue(property->obj()); | 1823         VisitForStackValue(property->obj()); | 
| 1824         VisitForStackValue(property->key()); | 1824         VisitForStackValue(property->key()); | 
| 1825         __ mov(edx, Operand(esp, kPointerSize));  // Object. | 1825         __ mov(LoadIC::ReceiverRegister(), Operand(esp, kPointerSize)); | 
| 1826         __ mov(ecx, Operand(esp, 0));             // Key. | 1826         __ mov(LoadIC::NameRegister(), Operand(esp, 0)); | 
| 1827       } else { | 1827       } else { | 
| 1828         VisitForStackValue(property->obj()); | 1828         VisitForStackValue(property->obj()); | 
| 1829         VisitForStackValue(property->key()); | 1829         VisitForStackValue(property->key()); | 
| 1830       } | 1830       } | 
| 1831       break; | 1831       break; | 
| 1832     } | 1832     } | 
| 1833   } | 1833   } | 
| 1834 | 1834 | 
| 1835   // For compound assignments we need another deoptimization point after the | 1835   // For compound assignments we need another deoptimization point after the | 
| 1836   // variable/property load. | 1836   // variable/property load. | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1957 | 1957 | 
| 1958     case Yield::DELEGATING: { | 1958     case Yield::DELEGATING: { | 
| 1959       VisitForStackValue(expr->generator_object()); | 1959       VisitForStackValue(expr->generator_object()); | 
| 1960 | 1960 | 
| 1961       // Initial stack layout is as follows: | 1961       // Initial stack layout is as follows: | 
| 1962       // [sp + 1 * kPointerSize] iter | 1962       // [sp + 1 * kPointerSize] iter | 
| 1963       // [sp + 0 * kPointerSize] g | 1963       // [sp + 0 * kPointerSize] g | 
| 1964 | 1964 | 
| 1965       Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 1965       Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 
| 1966       Label l_next, l_call, l_loop; | 1966       Label l_next, l_call, l_loop; | 
|  | 1967       Register load_receiver = LoadIC::ReceiverRegister(); | 
|  | 1968       Register load_name = LoadIC::NameRegister(); | 
|  | 1969 | 
| 1967       // Initial send value is undefined. | 1970       // Initial send value is undefined. | 
| 1968       __ mov(eax, isolate()->factory()->undefined_value()); | 1971       __ mov(eax, isolate()->factory()->undefined_value()); | 
| 1969       __ jmp(&l_next); | 1972       __ jmp(&l_next); | 
| 1970 | 1973 | 
| 1971       // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 1974       // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 
| 1972       __ bind(&l_catch); | 1975       __ bind(&l_catch); | 
| 1973       handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 1976       handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 
| 1974       __ mov(ecx, isolate()->factory()->throw_string());  // "throw" | 1977       __ mov(load_name, isolate()->factory()->throw_string());  // "throw" | 
| 1975       __ push(ecx);                                      // "throw" | 1978       __ push(load_name);                                       // "throw" | 
| 1976       __ push(Operand(esp, 2 * kPointerSize));           // iter | 1979       __ push(Operand(esp, 2 * kPointerSize));                  // iter | 
| 1977       __ push(eax);                                      // exception | 1980       __ push(eax);                                             // exception | 
| 1978       __ jmp(&l_call); | 1981       __ jmp(&l_call); | 
| 1979 | 1982 | 
| 1980       // try { received = %yield result } | 1983       // try { received = %yield result } | 
| 1981       // Shuffle the received result above a try handler and yield it without | 1984       // Shuffle the received result above a try handler and yield it without | 
| 1982       // re-boxing. | 1985       // re-boxing. | 
| 1983       __ bind(&l_try); | 1986       __ bind(&l_try); | 
| 1984       __ pop(eax);                                       // result | 1987       __ pop(eax);                                       // result | 
| 1985       __ PushTryHandler(StackHandler::CATCH, expr->index()); | 1988       __ PushTryHandler(StackHandler::CATCH, expr->index()); | 
| 1986       const int handler_size = StackHandlerConstants::kSize; | 1989       const int handler_size = StackHandlerConstants::kSize; | 
| 1987       __ push(eax);                                      // result | 1990       __ push(eax);                                      // result | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 2002       __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2005       __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 
| 2003       __ mov(context_register(), | 2006       __ mov(context_register(), | 
| 2004              Operand(ebp, StandardFrameConstants::kContextOffset)); | 2007              Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| 2005       __ pop(eax);                                       // result | 2008       __ pop(eax);                                       // result | 
| 2006       EmitReturnSequence(); | 2009       EmitReturnSequence(); | 
| 2007       __ bind(&l_resume);                                // received in eax | 2010       __ bind(&l_resume);                                // received in eax | 
| 2008       __ PopTryHandler(); | 2011       __ PopTryHandler(); | 
| 2009 | 2012 | 
| 2010       // receiver = iter; f = iter.next; arg = received; | 2013       // receiver = iter; f = iter.next; arg = received; | 
| 2011       __ bind(&l_next); | 2014       __ bind(&l_next); | 
| 2012       Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); |  | 
| 2013       Register keyedload_name = KeyedLoadIC::NameRegister(); |  | 
| 2014       ASSERT(keyedload_receiver.is(edx)); |  | 
| 2015       ASSERT(keyedload_name.is(ecx)); |  | 
| 2016 | 2015 | 
| 2017       __ mov(keyedload_name, | 2016       __ mov(load_name, isolate()->factory()->next_string()); | 
| 2018              isolate()->factory()->next_string());       // "next" | 2017       __ push(load_name);                           // "next" | 
| 2019       __ push(keyedload_name); | 2018       __ push(Operand(esp, 2 * kPointerSize));      // iter | 
| 2020       __ push(Operand(esp, 2 * kPointerSize));           // iter | 2019       __ push(eax);                                 // received | 
| 2021       __ push(eax);                                      // received |  | 
| 2022 | 2020 | 
| 2023       // result = receiver[f](arg); | 2021       // result = receiver[f](arg); | 
| 2024       __ bind(&l_call); | 2022       __ bind(&l_call); | 
| 2025       __ mov(keyedload_receiver, Operand(esp, kPointerSize)); | 2023       __ mov(load_receiver, Operand(esp, kPointerSize)); | 
| 2026       Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2024       Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 
| 2027       CallIC(ic, TypeFeedbackId::None()); | 2025       CallIC(ic, TypeFeedbackId::None()); | 
| 2028       __ mov(edi, eax); | 2026       __ mov(edi, eax); | 
| 2029       __ mov(Operand(esp, 2 * kPointerSize), edi); | 2027       __ mov(Operand(esp, 2 * kPointerSize), edi); | 
| 2030       CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2028       CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 
| 2031       __ CallStub(&stub); | 2029       __ CallStub(&stub); | 
| 2032 | 2030 | 
| 2033       __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2031       __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| 2034       __ Drop(1);  // The function is still on the stack; drop it. | 2032       __ Drop(1);  // The function is still on the stack; drop it. | 
| 2035 | 2033 | 
| 2036       // if (!result.done) goto l_try; | 2034       // if (!result.done) goto l_try; | 
| 2037       __ bind(&l_loop); | 2035       __ bind(&l_loop); | 
| 2038       __ push(eax);                                      // save result | 2036       __ push(eax);                                      // save result | 
| 2039       Register load_receiver = LoadIC::ReceiverRegister(); | 2037       __ Move(load_receiver, eax);                       // result | 
| 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, | 2038       __ mov(load_name, | 
| 2045              isolate()->factory()->done_string());       // "done" | 2039              isolate()->factory()->done_string());       // "done" | 
| 2046       CallLoadIC(NOT_CONTEXTUAL);                        // result.done in eax | 2040       CallLoadIC(NOT_CONTEXTUAL);                        // result.done in eax | 
| 2047       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2041       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 
| 2048       CallIC(bool_ic); | 2042       CallIC(bool_ic); | 
| 2049       __ test(eax, eax); | 2043       __ test(eax, eax); | 
| 2050       __ j(zero, &l_try); | 2044       __ j(zero, &l_try); | 
| 2051 | 2045 | 
| 2052       // result.value | 2046       // result.value | 
| 2053       __ pop(load_receiver);                              // result | 2047       __ pop(load_receiver);                              // result | 
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2503   context()->Plug(eax); | 2497   context()->Plug(eax); | 
| 2504 } | 2498 } | 
| 2505 | 2499 | 
| 2506 | 2500 | 
| 2507 void FullCodeGenerator::VisitProperty(Property* expr) { | 2501 void FullCodeGenerator::VisitProperty(Property* expr) { | 
| 2508   Comment cmnt(masm_, "[ Property"); | 2502   Comment cmnt(masm_, "[ Property"); | 
| 2509   Expression* key = expr->key(); | 2503   Expression* key = expr->key(); | 
| 2510 | 2504 | 
| 2511   if (key->IsPropertyName()) { | 2505   if (key->IsPropertyName()) { | 
| 2512     VisitForAccumulatorValue(expr->obj()); | 2506     VisitForAccumulatorValue(expr->obj()); | 
| 2513     __ mov(LoadIC::ReceiverRegister(), result_register()); | 2507     __ Move(LoadIC::ReceiverRegister(), result_register()); | 
| 2514     EmitNamedPropertyLoad(expr); | 2508     EmitNamedPropertyLoad(expr); | 
| 2515     PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2509     PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 
| 2516     context()->Plug(eax); | 2510     context()->Plug(eax); | 
| 2517   } else { | 2511   } else { | 
| 2518     VisitForStackValue(expr->obj()); | 2512     VisitForStackValue(expr->obj()); | 
| 2519     VisitForAccumulatorValue(expr->key()); | 2513     VisitForAccumulatorValue(expr->key()); | 
| 2520     __ pop(KeyedLoadIC::ReceiverRegister());                 // Object. | 2514     __ pop(LoadIC::ReceiverRegister());                  // Object. | 
| 2521     __ mov(KeyedLoadIC::NameRegister(), result_register());  // Key. | 2515     __ Move(LoadIC::NameRegister(), result_register());  // Key. | 
| 2522     EmitKeyedPropertyLoad(expr); | 2516     EmitKeyedPropertyLoad(expr); | 
| 2523     context()->Plug(eax); | 2517     context()->Plug(eax); | 
| 2524   } | 2518   } | 
| 2525 } | 2519 } | 
| 2526 | 2520 | 
| 2527 | 2521 | 
| 2528 void FullCodeGenerator::CallIC(Handle<Code> code, | 2522 void FullCodeGenerator::CallIC(Handle<Code> code, | 
| 2529                                TypeFeedbackId ast_id) { | 2523                                TypeFeedbackId ast_id) { | 
| 2530   ic_total_count_++; | 2524   ic_total_count_++; | 
| 2531   __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2525   __ call(code, RelocInfo::CODE_TARGET, ast_id); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2566 // Code common for calls using the IC. | 2560 // Code common for calls using the IC. | 
| 2567 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2561 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 
| 2568                                                 Expression* key) { | 2562                                                 Expression* key) { | 
| 2569   // Load the key. | 2563   // Load the key. | 
| 2570   VisitForAccumulatorValue(key); | 2564   VisitForAccumulatorValue(key); | 
| 2571 | 2565 | 
| 2572   Expression* callee = expr->expression(); | 2566   Expression* callee = expr->expression(); | 
| 2573 | 2567 | 
| 2574   // Load the function from the receiver. | 2568   // Load the function from the receiver. | 
| 2575   ASSERT(callee->IsProperty()); | 2569   ASSERT(callee->IsProperty()); | 
| 2576   __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); | 2570   __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); | 
| 2577   // Move the key into the right register for the keyed load IC. | 2571   __ mov(LoadIC::NameRegister(), eax); | 
| 2578   __ mov(KeyedLoadIC::NameRegister(), eax); |  | 
| 2579   EmitKeyedPropertyLoad(callee->AsProperty()); | 2572   EmitKeyedPropertyLoad(callee->AsProperty()); | 
| 2580   PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2573   PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 
| 2581 | 2574 | 
| 2582   // Push the target function under the receiver. | 2575   // Push the target function under the receiver. | 
| 2583   __ push(Operand(esp, 0)); | 2576   __ push(Operand(esp, 0)); | 
| 2584   __ mov(Operand(esp, kPointerSize), eax); | 2577   __ mov(Operand(esp, kPointerSize), eax); | 
| 2585 | 2578 | 
| 2586   EmitCall(expr, CallIC::METHOD); | 2579   EmitCall(expr, CallIC::METHOD); | 
| 2587 } | 2580 } | 
| 2588 | 2581 | 
| (...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4208   if (assign_type == VARIABLE) { | 4201   if (assign_type == VARIABLE) { | 
| 4209     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 4202     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 
| 4210     AccumulatorValueContext context(this); | 4203     AccumulatorValueContext context(this); | 
| 4211     EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4204     EmitVariableLoad(expr->expression()->AsVariableProxy()); | 
| 4212   } else { | 4205   } else { | 
| 4213     // Reserve space for result of postfix operation. | 4206     // Reserve space for result of postfix operation. | 
| 4214     if (expr->is_postfix() && !context()->IsEffect()) { | 4207     if (expr->is_postfix() && !context()->IsEffect()) { | 
| 4215       __ push(Immediate(Smi::FromInt(0))); | 4208       __ push(Immediate(Smi::FromInt(0))); | 
| 4216     } | 4209     } | 
| 4217     if (assign_type == NAMED_PROPERTY) { | 4210     if (assign_type == NAMED_PROPERTY) { | 
| 4218       // Put the object both on the stack and in edx. | 4211       // Put the object both on the stack and in the register. | 
| 4219       VisitForAccumulatorValue(prop->obj()); | 4212       VisitForStackValue(prop->obj()); | 
| 4220       ASSERT(!eax.is(LoadIC::ReceiverRegister())); | 4213       __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); | 
| 4221       __ push(eax); |  | 
| 4222       __ mov(LoadIC::ReceiverRegister(), eax); |  | 
| 4223       EmitNamedPropertyLoad(prop); | 4214       EmitNamedPropertyLoad(prop); | 
| 4224     } else { | 4215     } else { | 
| 4225       VisitForStackValue(prop->obj()); | 4216       VisitForStackValue(prop->obj()); | 
| 4226       VisitForStackValue(prop->key()); | 4217       VisitForStackValue(prop->key()); | 
| 4227       __ mov(KeyedLoadIC::ReceiverRegister(), | 4218       __ mov(LoadIC::ReceiverRegister(), | 
| 4228              Operand(esp, kPointerSize));                    // Object. | 4219              Operand(esp, kPointerSize));               // Object. | 
| 4229       __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0));  // Key. | 4220       __ mov(LoadIC::NameRegister(), Operand(esp, 0));  // Key. | 
| 4230       EmitKeyedPropertyLoad(prop); | 4221       EmitKeyedPropertyLoad(prop); | 
| 4231     } | 4222     } | 
| 4232   } | 4223   } | 
| 4233 | 4224 | 
| 4234   // We need a second deoptimization point after loading the value | 4225   // We need a second deoptimization point after loading the value | 
| 4235   // in case evaluating the property load my have a side effect. | 4226   // in case evaluating the property load my have a side effect. | 
| 4236   if (assign_type == VARIABLE) { | 4227   if (assign_type == VARIABLE) { | 
| 4237     PrepareForBailout(expr->expression(), TOS_REG); | 4228     PrepareForBailout(expr->expression(), TOS_REG); | 
| 4238   } else { | 4229   } else { | 
| 4239     PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4230     PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4811   ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4802   ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 
| 4812             Assembler::target_address_at(call_target_address, | 4803             Assembler::target_address_at(call_target_address, | 
| 4813                                          unoptimized_code)); | 4804                                          unoptimized_code)); | 
| 4814   return OSR_AFTER_STACK_CHECK; | 4805   return OSR_AFTER_STACK_CHECK; | 
| 4815 } | 4806 } | 
| 4816 | 4807 | 
| 4817 | 4808 | 
| 4818 } }  // namespace v8::internal | 4809 } }  // namespace v8::internal | 
| 4819 | 4810 | 
| 4820 #endif  // V8_TARGET_ARCH_IA32 | 4811 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|