OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 if (false_label_ != fall_through_) __ jmp(false_label_); | 617 if (false_label_ != fall_through_) __ jmp(false_label_); |
618 } | 618 } |
619 } | 619 } |
620 | 620 |
621 | 621 |
622 void FullCodeGenerator::DoTest(Expression* condition, | 622 void FullCodeGenerator::DoTest(Expression* condition, |
623 Label* if_true, | 623 Label* if_true, |
624 Label* if_false, | 624 Label* if_false, |
625 Label* fall_through) { | 625 Label* fall_through) { |
626 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 626 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
627 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 627 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
628 __ test(result_register(), result_register()); | 628 __ test(result_register(), result_register()); |
629 // The stub returns nonzero for true. | 629 // The stub returns nonzero for true. |
630 Split(not_zero, if_true, if_false, fall_through); | 630 Split(not_zero, if_true, if_false, fall_through); |
631 } | 631 } |
632 | 632 |
633 | 633 |
634 void FullCodeGenerator::Split(Condition cc, | 634 void FullCodeGenerator::Split(Condition cc, |
635 Label* if_true, | 635 Label* if_true, |
636 Label* if_false, | 636 Label* if_false, |
637 Label* fall_through) { | 637 Label* fall_through) { |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 __ cmp(edx, eax); | 968 __ cmp(edx, eax); |
969 __ j(not_equal, &next_test); | 969 __ j(not_equal, &next_test); |
970 __ Drop(1); // Switch value is no longer needed. | 970 __ Drop(1); // Switch value is no longer needed. |
971 __ jmp(clause->body_target()); | 971 __ jmp(clause->body_target()); |
972 __ bind(&slow_case); | 972 __ bind(&slow_case); |
973 } | 973 } |
974 | 974 |
975 // Record position before stub call for type feedback. | 975 // Record position before stub call for type feedback. |
976 SetSourcePosition(clause->position()); | 976 SetSourcePosition(clause->position()); |
977 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 977 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
978 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 978 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
979 patch_site.EmitPatchInfo(); | 979 patch_site.EmitPatchInfo(); |
980 __ test(eax, eax); | 980 __ test(eax, eax); |
981 __ j(not_equal, &next_test); | 981 __ j(not_equal, &next_test); |
982 __ Drop(1); // Switch value is no longer needed. | 982 __ Drop(1); // Switch value is no longer needed. |
983 __ jmp(clause->body_target()); | 983 __ jmp(clause->body_target()); |
984 } | 984 } |
985 | 985 |
986 // Discard the test value and jump to the default if present, otherwise to | 986 // Discard the test value and jump to the default if present, otherwise to |
987 // the end of the statement. | 987 // the end of the statement. |
988 __ bind(&next_test); | 988 __ bind(&next_test); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 // Load next context in chain. | 1314 // Load next context in chain. |
1315 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1315 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1316 __ jmp(&next); | 1316 __ jmp(&next); |
1317 __ bind(&fast); | 1317 __ bind(&fast); |
1318 } | 1318 } |
1319 | 1319 |
1320 // All extension objects were empty and it is safe to use a global | 1320 // All extension objects were empty and it is safe to use a global |
1321 // load IC call. | 1321 // load IC call. |
1322 __ mov(edx, GlobalObjectOperand()); | 1322 __ mov(edx, GlobalObjectOperand()); |
1323 __ mov(ecx, var->name()); | 1323 __ mov(ecx, var->name()); |
1324 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1324 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1325 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1325 ? NOT_CONTEXTUAL |
1326 ? RelocInfo::CODE_TARGET | 1326 : CONTEXTUAL; |
1327 : RelocInfo::CODE_TARGET_CONTEXT; | 1327 |
1328 CallIC(ic, mode); | 1328 CallLoadIC(mode); |
1329 } | 1329 } |
1330 | 1330 |
1331 | 1331 |
1332 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1332 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1333 Label* slow) { | 1333 Label* slow) { |
1334 ASSERT(var->IsContextSlot()); | 1334 ASSERT(var->IsContextSlot()); |
1335 Register context = esi; | 1335 Register context = esi; |
1336 Register temp = ebx; | 1336 Register temp = ebx; |
1337 | 1337 |
1338 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1338 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 | 1398 |
1399 // Three cases: global variables, lookup variables, and all other types of | 1399 // Three cases: global variables, lookup variables, and all other types of |
1400 // variables. | 1400 // variables. |
1401 switch (var->location()) { | 1401 switch (var->location()) { |
1402 case Variable::UNALLOCATED: { | 1402 case Variable::UNALLOCATED: { |
1403 Comment cmnt(masm_, "Global variable"); | 1403 Comment cmnt(masm_, "Global variable"); |
1404 // Use inline caching. Variable name is passed in ecx and the global | 1404 // Use inline caching. Variable name is passed in ecx and the global |
1405 // object in eax. | 1405 // object in eax. |
1406 __ mov(edx, GlobalObjectOperand()); | 1406 __ mov(edx, GlobalObjectOperand()); |
1407 __ mov(ecx, var->name()); | 1407 __ mov(ecx, var->name()); |
1408 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1408 CallLoadIC(CONTEXTUAL); |
1409 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
1410 context()->Plug(eax); | 1409 context()->Plug(eax); |
1411 break; | 1410 break; |
1412 } | 1411 } |
1413 | 1412 |
1414 case Variable::PARAMETER: | 1413 case Variable::PARAMETER: |
1415 case Variable::LOCAL: | 1414 case Variable::LOCAL: |
1416 case Variable::CONTEXT: { | 1415 case Variable::CONTEXT: { |
1417 Comment cmnt(masm_, var->IsContextSlot() | 1416 Comment cmnt(masm_, var->IsContextSlot() |
1418 ? "Context variable" | 1417 ? "Context variable" |
1419 : "Stack variable"); | 1418 : "Stack variable"); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1615 UNREACHABLE(); | 1614 UNREACHABLE(); |
1616 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1615 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1617 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1616 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
1618 // Fall through. | 1617 // Fall through. |
1619 case ObjectLiteral::Property::COMPUTED: | 1618 case ObjectLiteral::Property::COMPUTED: |
1620 if (key->value()->IsInternalizedString()) { | 1619 if (key->value()->IsInternalizedString()) { |
1621 if (property->emit_store()) { | 1620 if (property->emit_store()) { |
1622 VisitForAccumulatorValue(value); | 1621 VisitForAccumulatorValue(value); |
1623 __ mov(ecx, Immediate(key->value())); | 1622 __ mov(ecx, Immediate(key->value())); |
1624 __ mov(edx, Operand(esp, 0)); | 1623 __ mov(edx, Operand(esp, 0)); |
1625 Handle<Code> ic = is_classic_mode() | 1624 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
1626 ? isolate()->builtins()->StoreIC_Initialize() | |
1627 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
1628 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
1629 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1625 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1630 } else { | 1626 } else { |
1631 VisitForEffect(value); | 1627 VisitForEffect(value); |
1632 } | 1628 } |
1633 break; | 1629 break; |
1634 } | 1630 } |
1635 __ push(Operand(esp, 0)); // Duplicate receiver. | 1631 __ push(Operand(esp, 0)); // Duplicate receiver. |
1636 VisitForStackValue(key); | 1632 VisitForStackValue(key); |
1637 VisitForStackValue(value); | 1633 VisitForStackValue(value); |
1638 if (property->emit_store()) { | 1634 if (property->emit_store()) { |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2041 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2037 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
2042 CallIC(ic); | 2038 CallIC(ic); |
2043 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2039 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2044 __ Drop(1); // The key is still on the stack; drop it. | 2040 __ Drop(1); // The key is still on the stack; drop it. |
2045 | 2041 |
2046 // if (!result.done) goto l_try; | 2042 // if (!result.done) goto l_try; |
2047 __ bind(&l_loop); | 2043 __ bind(&l_loop); |
2048 __ push(eax); // save result | 2044 __ push(eax); // save result |
2049 __ mov(edx, eax); // result | 2045 __ mov(edx, eax); // result |
2050 __ mov(ecx, isolate()->factory()->done_string()); // "done" | 2046 __ mov(ecx, isolate()->factory()->done_string()); // "done" |
2051 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2047 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax |
2052 CallIC(done_ic); // result.done in eax | |
2053 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2048 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2054 CallIC(bool_ic); | 2049 CallIC(bool_ic); |
2055 __ test(eax, eax); | 2050 __ test(eax, eax); |
2056 __ j(zero, &l_try); | 2051 __ j(zero, &l_try); |
2057 | 2052 |
2058 // result.value | 2053 // result.value |
2059 __ pop(edx); // result | 2054 __ pop(edx); // result |
2060 __ mov(ecx, isolate()->factory()->value_string()); // "value" | 2055 __ mov(ecx, isolate()->factory()->value_string()); // "value" |
2061 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2056 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax |
2062 CallIC(value_ic); // result.value in eax | 2057 context()->DropAndPlug(2, eax); // drop iter and g |
2063 context()->DropAndPlug(2, eax); // drop iter and g | |
2064 break; | 2058 break; |
2065 } | 2059 } |
2066 } | 2060 } |
2067 } | 2061 } |
2068 | 2062 |
2069 | 2063 |
2070 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2064 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2071 Expression *value, | 2065 Expression *value, |
2072 JSGeneratorObject::ResumeMode resume_mode) { | 2066 JSGeneratorObject::ResumeMode resume_mode) { |
2073 // The value stays in eax, and is ultimately read by the resumed generator, as | 2067 // The value stays in eax, and is ultimately read by the resumed generator, as |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2196 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, | 2190 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
2197 ecx, edx, kDontSaveFPRegs); | 2191 ecx, edx, kDontSaveFPRegs); |
2198 } | 2192 } |
2199 | 2193 |
2200 | 2194 |
2201 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2195 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2202 SetSourcePosition(prop->position()); | 2196 SetSourcePosition(prop->position()); |
2203 Literal* key = prop->key()->AsLiteral(); | 2197 Literal* key = prop->key()->AsLiteral(); |
2204 ASSERT(!key->value()->IsSmi()); | 2198 ASSERT(!key->value()->IsSmi()); |
2205 __ mov(ecx, Immediate(key->value())); | 2199 __ mov(ecx, Immediate(key->value())); |
2206 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2200 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2207 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
2208 } | 2201 } |
2209 | 2202 |
2210 | 2203 |
2211 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2204 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2212 SetSourcePosition(prop->position()); | 2205 SetSourcePosition(prop->position()); |
2213 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2206 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2214 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2207 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2215 } | 2208 } |
2216 | 2209 |
2217 | 2210 |
2218 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2211 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2219 Token::Value op, | 2212 Token::Value op, |
2220 OverwriteMode mode, | 2213 OverwriteMode mode, |
2221 Expression* left, | 2214 Expression* left, |
2222 Expression* right) { | 2215 Expression* right) { |
2223 // Do combined smi check of the operands. Left operand is on the | 2216 // Do combined smi check of the operands. Left operand is on the |
2224 // stack. Right operand is in eax. | 2217 // stack. Right operand is in eax. |
2225 Label smi_case, done, stub_call; | 2218 Label smi_case, done, stub_call; |
2226 __ pop(edx); | 2219 __ pop(edx); |
2227 __ mov(ecx, eax); | 2220 __ mov(ecx, eax); |
2228 __ or_(eax, edx); | 2221 __ or_(eax, edx); |
2229 JumpPatchSite patch_site(masm_); | 2222 JumpPatchSite patch_site(masm_); |
2230 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 2223 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
2231 | 2224 |
2232 __ bind(&stub_call); | 2225 __ bind(&stub_call); |
2233 __ mov(eax, ecx); | 2226 __ mov(eax, ecx); |
2234 BinaryOpICStub stub(op, mode); | 2227 BinaryOpICStub stub(op, mode); |
2235 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2228 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
2236 expr->BinaryOperationFeedbackId()); | 2229 expr->BinaryOperationFeedbackId()); |
2237 patch_site.EmitPatchInfo(); | 2230 patch_site.EmitPatchInfo(); |
2238 __ jmp(&done, Label::kNear); | 2231 __ jmp(&done, Label::kNear); |
2239 | 2232 |
2240 // Smi case. | 2233 // Smi case. |
2241 __ bind(&smi_case); | 2234 __ bind(&smi_case); |
2242 __ mov(eax, edx); // Copy left operand in case of a stub call. | 2235 __ mov(eax, edx); // Copy left operand in case of a stub call. |
2243 | 2236 |
2244 switch (op) { | 2237 switch (op) { |
2245 case Token::SAR: | 2238 case Token::SAR: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2311 context()->Plug(eax); | 2304 context()->Plug(eax); |
2312 } | 2305 } |
2313 | 2306 |
2314 | 2307 |
2315 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2308 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2316 Token::Value op, | 2309 Token::Value op, |
2317 OverwriteMode mode) { | 2310 OverwriteMode mode) { |
2318 __ pop(edx); | 2311 __ pop(edx); |
2319 BinaryOpICStub stub(op, mode); | 2312 BinaryOpICStub stub(op, mode); |
2320 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2313 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2321 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2314 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
2322 expr->BinaryOperationFeedbackId()); | 2315 expr->BinaryOperationFeedbackId()); |
2323 patch_site.EmitPatchInfo(); | 2316 patch_site.EmitPatchInfo(); |
2324 context()->Plug(eax); | 2317 context()->Plug(eax); |
2325 } | 2318 } |
2326 | 2319 |
2327 | 2320 |
2328 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2321 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2329 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2322 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
2330 // ReferenceError' on the left-hand side. | 2323 // ReferenceError' on the left-hand side. |
2331 if (!expr->IsValidLeftHandSide()) { | 2324 if (!expr->IsValidLeftHandSide()) { |
(...skipping 18 matching lines...) Expand all Loading... |
2350 EffectContext context(this); | 2343 EffectContext context(this); |
2351 EmitVariableAssignment(var, Token::ASSIGN); | 2344 EmitVariableAssignment(var, Token::ASSIGN); |
2352 break; | 2345 break; |
2353 } | 2346 } |
2354 case NAMED_PROPERTY: { | 2347 case NAMED_PROPERTY: { |
2355 __ push(eax); // Preserve value. | 2348 __ push(eax); // Preserve value. |
2356 VisitForAccumulatorValue(prop->obj()); | 2349 VisitForAccumulatorValue(prop->obj()); |
2357 __ mov(edx, eax); | 2350 __ mov(edx, eax); |
2358 __ pop(eax); // Restore value. | 2351 __ pop(eax); // Restore value. |
2359 __ mov(ecx, prop->key()->AsLiteral()->value()); | 2352 __ mov(ecx, prop->key()->AsLiteral()->value()); |
2360 Handle<Code> ic = is_classic_mode() | 2353 CallStoreIC(NOT_CONTEXTUAL); |
2361 ? isolate()->builtins()->StoreIC_Initialize() | |
2362 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2363 CallIC(ic); | |
2364 break; | 2354 break; |
2365 } | 2355 } |
2366 case KEYED_PROPERTY: { | 2356 case KEYED_PROPERTY: { |
2367 __ push(eax); // Preserve value. | 2357 __ push(eax); // Preserve value. |
2368 VisitForStackValue(prop->obj()); | 2358 VisitForStackValue(prop->obj()); |
2369 VisitForAccumulatorValue(prop->key()); | 2359 VisitForAccumulatorValue(prop->key()); |
2370 __ mov(ecx, eax); | 2360 __ mov(ecx, eax); |
2371 __ pop(edx); // Receiver. | 2361 __ pop(edx); // Receiver. |
2372 __ pop(eax); // Restore value. | 2362 __ pop(eax); // Restore value. |
2373 Handle<Code> ic = is_classic_mode() | 2363 Handle<Code> ic = is_classic_mode() |
2374 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2364 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2375 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2365 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2376 CallIC(ic); | 2366 CallIC(ic); |
2377 break; | 2367 break; |
2378 } | 2368 } |
2379 } | 2369 } |
2380 context()->Plug(eax); | 2370 context()->Plug(eax); |
2381 } | 2371 } |
2382 | 2372 |
2383 | 2373 |
2384 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2374 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2385 Token::Value op) { | 2375 Token::Value op) { |
2386 if (var->IsUnallocated()) { | 2376 if (var->IsUnallocated()) { |
2387 // Global var, const, or let. | 2377 // Global var, const, or let. |
2388 __ mov(ecx, var->name()); | 2378 __ mov(ecx, var->name()); |
2389 __ mov(edx, GlobalObjectOperand()); | 2379 __ mov(edx, GlobalObjectOperand()); |
2390 Handle<Code> ic = is_classic_mode() | 2380 CallStoreIC(CONTEXTUAL); |
2391 ? isolate()->builtins()->StoreIC_Initialize() | |
2392 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2393 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
2394 | |
2395 } else if (op == Token::INIT_CONST) { | 2381 } else if (op == Token::INIT_CONST) { |
2396 // Const initializers need a write barrier. | 2382 // Const initializers need a write barrier. |
2397 ASSERT(!var->IsParameter()); // No const parameters. | 2383 ASSERT(!var->IsParameter()); // No const parameters. |
2398 if (var->IsStackLocal()) { | 2384 if (var->IsStackLocal()) { |
2399 Label skip; | 2385 Label skip; |
2400 __ mov(edx, StackOperand(var)); | 2386 __ mov(edx, StackOperand(var)); |
2401 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2387 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2402 __ j(not_equal, &skip); | 2388 __ j(not_equal, &skip); |
2403 __ mov(StackOperand(var), eax); | 2389 __ mov(StackOperand(var), eax); |
2404 __ bind(&skip); | 2390 __ bind(&skip); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2478 // esp[0] : receiver | 2464 // esp[0] : receiver |
2479 | 2465 |
2480 Property* prop = expr->target()->AsProperty(); | 2466 Property* prop = expr->target()->AsProperty(); |
2481 ASSERT(prop != NULL); | 2467 ASSERT(prop != NULL); |
2482 ASSERT(prop->key()->AsLiteral() != NULL); | 2468 ASSERT(prop->key()->AsLiteral() != NULL); |
2483 | 2469 |
2484 // Record source code position before IC call. | 2470 // Record source code position before IC call. |
2485 SetSourcePosition(expr->position()); | 2471 SetSourcePosition(expr->position()); |
2486 __ mov(ecx, prop->key()->AsLiteral()->value()); | 2472 __ mov(ecx, prop->key()->AsLiteral()->value()); |
2487 __ pop(edx); | 2473 __ pop(edx); |
2488 Handle<Code> ic = is_classic_mode() | 2474 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
2489 ? isolate()->builtins()->StoreIC_Initialize() | |
2490 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2491 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
2492 | |
2493 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2475 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2494 context()->Plug(eax); | 2476 context()->Plug(eax); |
2495 } | 2477 } |
2496 | 2478 |
2497 | 2479 |
2498 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2480 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2499 // Assignment to a property, using a keyed store IC. | 2481 // Assignment to a property, using a keyed store IC. |
2500 // eax : value | 2482 // eax : value |
2501 // esp[0] : key | 2483 // esp[0] : key |
2502 // esp[kPointerSize] : receiver | 2484 // esp[kPointerSize] : receiver |
2503 | 2485 |
2504 __ pop(ecx); // Key. | 2486 __ pop(ecx); // Key. |
2505 __ pop(edx); | 2487 __ pop(edx); |
2506 // Record source code position before IC call. | 2488 // Record source code position before IC call. |
2507 SetSourcePosition(expr->position()); | 2489 SetSourcePosition(expr->position()); |
2508 Handle<Code> ic = is_classic_mode() | 2490 Handle<Code> ic = is_classic_mode() |
2509 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2491 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2510 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2492 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2511 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2493 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
2512 | 2494 |
2513 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2495 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2514 context()->Plug(eax); | 2496 context()->Plug(eax); |
2515 } | 2497 } |
2516 | 2498 |
2517 | 2499 |
2518 void FullCodeGenerator::VisitProperty(Property* expr) { | 2500 void FullCodeGenerator::VisitProperty(Property* expr) { |
2519 Comment cmnt(masm_, "[ Property"); | 2501 Comment cmnt(masm_, "[ Property"); |
2520 Expression* key = expr->key(); | 2502 Expression* key = expr->key(); |
2521 | 2503 |
2522 if (key->IsPropertyName()) { | 2504 if (key->IsPropertyName()) { |
2523 VisitForAccumulatorValue(expr->obj()); | 2505 VisitForAccumulatorValue(expr->obj()); |
2524 __ mov(edx, result_register()); | 2506 __ mov(edx, result_register()); |
2525 EmitNamedPropertyLoad(expr); | 2507 EmitNamedPropertyLoad(expr); |
2526 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2508 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2527 context()->Plug(eax); | 2509 context()->Plug(eax); |
2528 } else { | 2510 } else { |
2529 VisitForStackValue(expr->obj()); | 2511 VisitForStackValue(expr->obj()); |
2530 VisitForAccumulatorValue(expr->key()); | 2512 VisitForAccumulatorValue(expr->key()); |
2531 __ pop(edx); // Object. | 2513 __ pop(edx); // Object. |
2532 __ mov(ecx, result_register()); // Key. | 2514 __ mov(ecx, result_register()); // Key. |
2533 EmitKeyedPropertyLoad(expr); | 2515 EmitKeyedPropertyLoad(expr); |
2534 context()->Plug(eax); | 2516 context()->Plug(eax); |
2535 } | 2517 } |
2536 } | 2518 } |
2537 | 2519 |
2538 | 2520 |
2539 void FullCodeGenerator::CallIC(Handle<Code> code, | 2521 void FullCodeGenerator::CallIC(Handle<Code> code, |
2540 RelocInfo::Mode rmode, | 2522 ContextualMode mode, |
2541 TypeFeedbackId ast_id) { | 2523 TypeFeedbackId ast_id) { |
2542 ic_total_count_++; | 2524 ic_total_count_++; |
2543 __ call(code, rmode, ast_id); | 2525 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
| 2526 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
2544 } | 2527 } |
2545 | 2528 |
2546 | 2529 |
2547 | 2530 |
2548 | 2531 |
2549 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2532 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
2550 Handle<Object> name, | 2533 Handle<Object> name, |
2551 RelocInfo::Mode mode) { | 2534 ContextualMode mode) { |
2552 // Code common for calls using the IC. | 2535 // Code common for calls using the IC. |
2553 ZoneList<Expression*>* args = expr->arguments(); | 2536 ZoneList<Expression*>* args = expr->arguments(); |
2554 int arg_count = args->length(); | 2537 int arg_count = args->length(); |
2555 { PreservePositionScope scope(masm()->positions_recorder()); | 2538 { PreservePositionScope scope(masm()->positions_recorder()); |
2556 for (int i = 0; i < arg_count; i++) { | 2539 for (int i = 0; i < arg_count; i++) { |
2557 VisitForStackValue(args->at(i)); | 2540 VisitForStackValue(args->at(i)); |
2558 } | 2541 } |
2559 __ Set(ecx, Immediate(name)); | 2542 __ Set(ecx, Immediate(name)); |
2560 } | 2543 } |
2561 // Record source position of the IC call. | 2544 // Record source position of the IC call. |
2562 SetSourcePosition(expr->position()); | 2545 SetSourcePosition(expr->position()); |
2563 Handle<Code> ic = | 2546 Handle<Code> ic = |
2564 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2547 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
2565 CallIC(ic, mode, expr->CallFeedbackId()); | 2548 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2549 ? TypeFeedbackId::None() |
| 2550 : expr->CallFeedbackId(); |
| 2551 CallIC(ic, mode, ast_id); |
2566 RecordJSReturnSite(expr); | 2552 RecordJSReturnSite(expr); |
2567 // Restore context register. | 2553 // Restore context register. |
2568 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2554 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2569 context()->Plug(eax); | 2555 context()->Plug(eax); |
2570 } | 2556 } |
2571 | 2557 |
2572 | 2558 |
2573 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2559 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2574 Expression* key) { | 2560 Expression* key) { |
2575 // Load the key. | 2561 // Load the key. |
(...skipping 11 matching lines...) Expand all Loading... |
2587 { PreservePositionScope scope(masm()->positions_recorder()); | 2573 { PreservePositionScope scope(masm()->positions_recorder()); |
2588 for (int i = 0; i < arg_count; i++) { | 2574 for (int i = 0; i < arg_count; i++) { |
2589 VisitForStackValue(args->at(i)); | 2575 VisitForStackValue(args->at(i)); |
2590 } | 2576 } |
2591 } | 2577 } |
2592 // Record source position of the IC call. | 2578 // Record source position of the IC call. |
2593 SetSourcePosition(expr->position()); | 2579 SetSourcePosition(expr->position()); |
2594 Handle<Code> ic = | 2580 Handle<Code> ic = |
2595 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2581 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
2596 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. | 2582 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. |
2597 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2583 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
2598 RecordJSReturnSite(expr); | 2584 RecordJSReturnSite(expr); |
2599 // Restore context register. | 2585 // Restore context register. |
2600 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2586 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2601 context()->DropAndPlug(1, eax); // Drop the key still on the stack. | 2587 context()->DropAndPlug(1, eax); // Drop the key still on the stack. |
2602 } | 2588 } |
2603 | 2589 |
2604 | 2590 |
2605 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2591 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2606 // Code common for calls using the call stub. | 2592 // Code common for calls using the call stub. |
2607 ZoneList<Expression*>* args = expr->arguments(); | 2593 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2697 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2683 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2698 __ CallStub(&stub); | 2684 __ CallStub(&stub); |
2699 RecordJSReturnSite(expr); | 2685 RecordJSReturnSite(expr); |
2700 // Restore context register. | 2686 // Restore context register. |
2701 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2687 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2702 context()->DropAndPlug(1, eax); | 2688 context()->DropAndPlug(1, eax); |
2703 | 2689 |
2704 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2690 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
2705 // Push global object as receiver for the call IC. | 2691 // Push global object as receiver for the call IC. |
2706 __ push(GlobalObjectOperand()); | 2692 __ push(GlobalObjectOperand()); |
2707 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2693 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
2708 | |
2709 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2694 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
2710 // Call to a lookup slot (dynamically introduced variable). | 2695 // Call to a lookup slot (dynamically introduced variable). |
2711 Label slow, done; | 2696 Label slow, done; |
2712 { PreservePositionScope scope(masm()->positions_recorder()); | 2697 { PreservePositionScope scope(masm()->positions_recorder()); |
2713 // Generate code for loading from variables potentially shadowed by | 2698 // Generate code for loading from variables potentially shadowed by |
2714 // eval-introduced variables. | 2699 // eval-introduced variables. |
2715 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2700 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2716 } | 2701 } |
2717 __ bind(&slow); | 2702 __ bind(&slow); |
2718 // Call the runtime to find the function to call (returned in eax) and | 2703 // Call the runtime to find the function to call (returned in eax) and |
(...skipping 23 matching lines...) Expand all Loading... |
2742 // implicitly the global object. | 2727 // implicitly the global object. |
2743 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2728 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
2744 | 2729 |
2745 } else if (property != NULL) { | 2730 } else if (property != NULL) { |
2746 { PreservePositionScope scope(masm()->positions_recorder()); | 2731 { PreservePositionScope scope(masm()->positions_recorder()); |
2747 VisitForStackValue(property->obj()); | 2732 VisitForStackValue(property->obj()); |
2748 } | 2733 } |
2749 if (property->key()->IsPropertyName()) { | 2734 if (property->key()->IsPropertyName()) { |
2750 EmitCallWithIC(expr, | 2735 EmitCallWithIC(expr, |
2751 property->key()->AsLiteral()->value(), | 2736 property->key()->AsLiteral()->value(), |
2752 RelocInfo::CODE_TARGET); | 2737 NOT_CONTEXTUAL); |
2753 } else { | 2738 } else { |
2754 EmitKeyedCallWithIC(expr, property->key()); | 2739 EmitKeyedCallWithIC(expr, property->key()); |
2755 } | 2740 } |
2756 | 2741 |
2757 } else { | 2742 } else { |
2758 // Call to an arbitrary expression not handled specially above. | 2743 // Call to an arbitrary expression not handled specially above. |
2759 { PreservePositionScope scope(masm()->positions_recorder()); | 2744 { PreservePositionScope scope(masm()->positions_recorder()); |
2760 VisitForStackValue(callee); | 2745 VisitForStackValue(callee); |
2761 } | 2746 } |
2762 // Load global receiver object. | 2747 // Load global receiver object. |
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4135 | 4120 |
4136 // Push the arguments ("left-to-right"). | 4121 // Push the arguments ("left-to-right"). |
4137 int arg_count = args->length(); | 4122 int arg_count = args->length(); |
4138 for (int i = 0; i < arg_count; i++) { | 4123 for (int i = 0; i < arg_count; i++) { |
4139 VisitForStackValue(args->at(i)); | 4124 VisitForStackValue(args->at(i)); |
4140 } | 4125 } |
4141 | 4126 |
4142 if (expr->is_jsruntime()) { | 4127 if (expr->is_jsruntime()) { |
4143 // Call the JS runtime function via a call IC. | 4128 // Call the JS runtime function via a call IC. |
4144 __ Set(ecx, Immediate(expr->name())); | 4129 __ Set(ecx, Immediate(expr->name())); |
4145 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4130 ContextualMode mode = NOT_CONTEXTUAL; |
4146 Handle<Code> ic = | 4131 Handle<Code> ic = |
4147 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4132 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
4148 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4133 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
4149 // Restore context register. | 4134 // Restore context register. |
4150 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4135 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4151 } else { | 4136 } else { |
4152 // Call the C runtime function. | 4137 // Call the C runtime function. |
4153 __ CallRuntime(expr->function(), arg_count); | 4138 __ CallRuntime(expr->function(), arg_count); |
4154 } | 4139 } |
4155 context()->Plug(eax); | 4140 context()->Plug(eax); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4395 | 4380 |
4396 // Record position before stub call. | 4381 // Record position before stub call. |
4397 SetSourcePosition(expr->position()); | 4382 SetSourcePosition(expr->position()); |
4398 | 4383 |
4399 // Call stub for +1/-1. | 4384 // Call stub for +1/-1. |
4400 __ bind(&stub_call); | 4385 __ bind(&stub_call); |
4401 __ mov(edx, eax); | 4386 __ mov(edx, eax); |
4402 __ mov(eax, Immediate(Smi::FromInt(1))); | 4387 __ mov(eax, Immediate(Smi::FromInt(1))); |
4403 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); | 4388 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); |
4404 CallIC(stub.GetCode(isolate()), | 4389 CallIC(stub.GetCode(isolate()), |
4405 RelocInfo::CODE_TARGET, | 4390 NOT_CONTEXTUAL, |
4406 expr->CountBinOpFeedbackId()); | 4391 expr->CountBinOpFeedbackId()); |
4407 patch_site.EmitPatchInfo(); | 4392 patch_site.EmitPatchInfo(); |
4408 __ bind(&done); | 4393 __ bind(&done); |
4409 | 4394 |
4410 // Store the value returned in eax. | 4395 // Store the value returned in eax. |
4411 switch (assign_type) { | 4396 switch (assign_type) { |
4412 case VARIABLE: | 4397 case VARIABLE: |
4413 if (expr->is_postfix()) { | 4398 if (expr->is_postfix()) { |
4414 // Perform the assignment as if via '='. | 4399 // Perform the assignment as if via '='. |
4415 { EffectContext context(this); | 4400 { EffectContext context(this); |
(...skipping 11 matching lines...) Expand all Loading... |
4427 // Perform the assignment as if via '='. | 4412 // Perform the assignment as if via '='. |
4428 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4413 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4429 Token::ASSIGN); | 4414 Token::ASSIGN); |
4430 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4415 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4431 context()->Plug(eax); | 4416 context()->Plug(eax); |
4432 } | 4417 } |
4433 break; | 4418 break; |
4434 case NAMED_PROPERTY: { | 4419 case NAMED_PROPERTY: { |
4435 __ mov(ecx, prop->key()->AsLiteral()->value()); | 4420 __ mov(ecx, prop->key()->AsLiteral()->value()); |
4436 __ pop(edx); | 4421 __ pop(edx); |
4437 Handle<Code> ic = is_classic_mode() | 4422 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
4438 ? isolate()->builtins()->StoreIC_Initialize() | |
4439 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
4440 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
4441 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4423 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4442 if (expr->is_postfix()) { | 4424 if (expr->is_postfix()) { |
4443 if (!context()->IsEffect()) { | 4425 if (!context()->IsEffect()) { |
4444 context()->PlugTOS(); | 4426 context()->PlugTOS(); |
4445 } | 4427 } |
4446 } else { | 4428 } else { |
4447 context()->Plug(eax); | 4429 context()->Plug(eax); |
4448 } | 4430 } |
4449 break; | 4431 break; |
4450 } | 4432 } |
4451 case KEYED_PROPERTY: { | 4433 case KEYED_PROPERTY: { |
4452 __ pop(ecx); | 4434 __ pop(ecx); |
4453 __ pop(edx); | 4435 __ pop(edx); |
4454 Handle<Code> ic = is_classic_mode() | 4436 Handle<Code> ic = is_classic_mode() |
4455 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4437 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4456 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4438 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4457 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4439 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
4458 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4440 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4459 if (expr->is_postfix()) { | 4441 if (expr->is_postfix()) { |
4460 // Result is on the stack | 4442 // Result is on the stack |
4461 if (!context()->IsEffect()) { | 4443 if (!context()->IsEffect()) { |
4462 context()->PlugTOS(); | 4444 context()->PlugTOS(); |
4463 } | 4445 } |
4464 } else { | 4446 } else { |
4465 context()->Plug(eax); | 4447 context()->Plug(eax); |
4466 } | 4448 } |
4467 break; | 4449 break; |
4468 } | 4450 } |
4469 } | 4451 } |
4470 } | 4452 } |
4471 | 4453 |
4472 | 4454 |
4473 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4455 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4474 VariableProxy* proxy = expr->AsVariableProxy(); | 4456 VariableProxy* proxy = expr->AsVariableProxy(); |
4475 ASSERT(!context()->IsEffect()); | 4457 ASSERT(!context()->IsEffect()); |
4476 ASSERT(!context()->IsTest()); | 4458 ASSERT(!context()->IsTest()); |
4477 | 4459 |
4478 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4460 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4479 Comment cmnt(masm_, "Global variable"); | 4461 Comment cmnt(masm_, "Global variable"); |
4480 __ mov(edx, GlobalObjectOperand()); | 4462 __ mov(edx, GlobalObjectOperand()); |
4481 __ mov(ecx, Immediate(proxy->name())); | 4463 __ mov(ecx, Immediate(proxy->name())); |
4482 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
4483 // Use a regular load, not a contextual load, to avoid a reference | 4464 // Use a regular load, not a contextual load, to avoid a reference |
4484 // error. | 4465 // error. |
4485 CallIC(ic); | 4466 CallLoadIC(NOT_CONTEXTUAL); |
4486 PrepareForBailout(expr, TOS_REG); | 4467 PrepareForBailout(expr, TOS_REG); |
4487 context()->Plug(eax); | 4468 context()->Plug(eax); |
4488 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4469 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4489 Label done, slow; | 4470 Label done, slow; |
4490 | 4471 |
4491 // Generate code for loading from variables potentially shadowed | 4472 // Generate code for loading from variables potentially shadowed |
4492 // by eval-introduced variables. | 4473 // by eval-introduced variables. |
4493 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4474 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
4494 | 4475 |
4495 __ bind(&slow); | 4476 __ bind(&slow); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4637 __ or_(ecx, eax); | 4618 __ or_(ecx, eax); |
4638 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 4619 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
4639 __ cmp(edx, eax); | 4620 __ cmp(edx, eax); |
4640 Split(cc, if_true, if_false, NULL); | 4621 Split(cc, if_true, if_false, NULL); |
4641 __ bind(&slow_case); | 4622 __ bind(&slow_case); |
4642 } | 4623 } |
4643 | 4624 |
4644 // Record position and call the compare IC. | 4625 // Record position and call the compare IC. |
4645 SetSourcePosition(expr->position()); | 4626 SetSourcePosition(expr->position()); |
4646 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4627 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
4647 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4628 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
4648 patch_site.EmitPatchInfo(); | 4629 patch_site.EmitPatchInfo(); |
4649 | 4630 |
4650 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4631 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4651 __ test(eax, eax); | 4632 __ test(eax, eax); |
4652 Split(cc, if_true, if_false, fall_through); | 4633 Split(cc, if_true, if_false, fall_through); |
4653 } | 4634 } |
4654 } | 4635 } |
4655 | 4636 |
4656 // Convert the result of the comparison into one expected for this | 4637 // Convert the result of the comparison into one expected for this |
4657 // expression's context. | 4638 // expression's context. |
(...skipping 15 matching lines...) Expand all Loading... |
4673 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4654 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4674 | 4655 |
4675 Handle<Object> nil_value = nil == kNullValue | 4656 Handle<Object> nil_value = nil == kNullValue |
4676 ? isolate()->factory()->null_value() | 4657 ? isolate()->factory()->null_value() |
4677 : isolate()->factory()->undefined_value(); | 4658 : isolate()->factory()->undefined_value(); |
4678 if (expr->op() == Token::EQ_STRICT) { | 4659 if (expr->op() == Token::EQ_STRICT) { |
4679 __ cmp(eax, nil_value); | 4660 __ cmp(eax, nil_value); |
4680 Split(equal, if_true, if_false, fall_through); | 4661 Split(equal, if_true, if_false, fall_through); |
4681 } else { | 4662 } else { |
4682 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4663 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
4683 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4664 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
4684 __ test(eax, eax); | 4665 __ test(eax, eax); |
4685 Split(not_zero, if_true, if_false, fall_through); | 4666 Split(not_zero, if_true, if_false, fall_through); |
4686 } | 4667 } |
4687 context()->Plug(if_true, if_false); | 4668 context()->Plug(if_true, if_false); |
4688 } | 4669 } |
4689 | 4670 |
4690 | 4671 |
4691 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4672 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
4692 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 4673 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
4693 context()->Plug(eax); | 4674 context()->Plug(eax); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4901 | 4882 |
4902 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4883 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4903 Assembler::target_address_at(call_target_address)); | 4884 Assembler::target_address_at(call_target_address)); |
4904 return OSR_AFTER_STACK_CHECK; | 4885 return OSR_AFTER_STACK_CHECK; |
4905 } | 4886 } |
4906 | 4887 |
4907 | 4888 |
4908 } } // namespace v8::internal | 4889 } } // namespace v8::internal |
4909 | 4890 |
4910 #endif // V8_TARGET_ARCH_IA32 | 4891 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |