| 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 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 } | 664 } |
| 665 } | 665 } |
| 666 | 666 |
| 667 | 667 |
| 668 void FullCodeGenerator::DoTest(Expression* condition, | 668 void FullCodeGenerator::DoTest(Expression* condition, |
| 669 Label* if_true, | 669 Label* if_true, |
| 670 Label* if_false, | 670 Label* if_false, |
| 671 Label* fall_through) { | 671 Label* fall_through) { |
| 672 __ mov(a0, result_register()); | 672 __ mov(a0, result_register()); |
| 673 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 673 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
| 674 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 674 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
| 675 __ mov(at, zero_reg); | 675 __ mov(at, zero_reg); |
| 676 Split(ne, v0, Operand(at), if_true, if_false, fall_through); | 676 Split(ne, v0, Operand(at), if_true, if_false, fall_through); |
| 677 } | 677 } |
| 678 | 678 |
| 679 | 679 |
| 680 void FullCodeGenerator::Split(Condition cc, | 680 void FullCodeGenerator::Split(Condition cc, |
| 681 Register lhs, | 681 Register lhs, |
| 682 const Operand& rhs, | 682 const Operand& rhs, |
| 683 Label* if_true, | 683 Label* if_true, |
| 684 Label* if_false, | 684 Label* if_false, |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 __ Branch(&next_test, ne, a1, Operand(a0)); | 1029 __ Branch(&next_test, ne, a1, Operand(a0)); |
| 1030 __ Drop(1); // Switch value is no longer needed. | 1030 __ Drop(1); // Switch value is no longer needed. |
| 1031 __ Branch(clause->body_target()); | 1031 __ Branch(clause->body_target()); |
| 1032 | 1032 |
| 1033 __ bind(&slow_case); | 1033 __ bind(&slow_case); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 // Record position before stub call for type feedback. | 1036 // Record position before stub call for type feedback. |
| 1037 SetSourcePosition(clause->position()); | 1037 SetSourcePosition(clause->position()); |
| 1038 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1038 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
| 1039 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 1039 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
| 1040 patch_site.EmitPatchInfo(); | 1040 patch_site.EmitPatchInfo(); |
| 1041 | 1041 |
| 1042 __ Branch(&next_test, ne, v0, Operand(zero_reg)); | 1042 __ Branch(&next_test, ne, v0, Operand(zero_reg)); |
| 1043 __ Drop(1); // Switch value is no longer needed. | 1043 __ Drop(1); // Switch value is no longer needed. |
| 1044 __ Branch(clause->body_target()); | 1044 __ Branch(clause->body_target()); |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 // Discard the test value and jump to the default if present, otherwise to | 1047 // Discard the test value and jump to the default if present, otherwise to |
| 1048 // the end of the statement. | 1048 // the end of the statement. |
| 1049 __ bind(&next_test); | 1049 __ bind(&next_test); |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1383 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
| 1384 __ Branch(slow, ne, temp, Operand(zero_reg)); | 1384 __ Branch(slow, ne, temp, Operand(zero_reg)); |
| 1385 // Load next context in chain. | 1385 // Load next context in chain. |
| 1386 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1386 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
| 1387 __ Branch(&loop); | 1387 __ Branch(&loop); |
| 1388 __ bind(&fast); | 1388 __ bind(&fast); |
| 1389 } | 1389 } |
| 1390 | 1390 |
| 1391 __ lw(a0, GlobalObjectOperand()); | 1391 __ lw(a0, GlobalObjectOperand()); |
| 1392 __ li(a2, Operand(var->name())); | 1392 __ li(a2, Operand(var->name())); |
| 1393 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1393 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1394 ? RelocInfo::CODE_TARGET | 1394 ? NOT_CONTEXTUAL |
| 1395 : RelocInfo::CODE_TARGET_CONTEXT; | 1395 : CONTEXTUAL; |
| 1396 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1396 CallLoadIC(mode); |
| 1397 CallIC(ic, mode); | |
| 1398 } | 1397 } |
| 1399 | 1398 |
| 1400 | 1399 |
| 1401 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1400 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1402 Label* slow) { | 1401 Label* slow) { |
| 1403 ASSERT(var->IsContextSlot()); | 1402 ASSERT(var->IsContextSlot()); |
| 1404 Register context = cp; | 1403 Register context = cp; |
| 1405 Register next = a3; | 1404 Register next = a3; |
| 1406 Register temp = t0; | 1405 Register temp = t0; |
| 1407 | 1406 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 | 1469 |
| 1471 // Three cases: global variables, lookup variables, and all other types of | 1470 // Three cases: global variables, lookup variables, and all other types of |
| 1472 // variables. | 1471 // variables. |
| 1473 switch (var->location()) { | 1472 switch (var->location()) { |
| 1474 case Variable::UNALLOCATED: { | 1473 case Variable::UNALLOCATED: { |
| 1475 Comment cmnt(masm_, "Global variable"); | 1474 Comment cmnt(masm_, "Global variable"); |
| 1476 // Use inline caching. Variable name is passed in a2 and the global | 1475 // Use inline caching. Variable name is passed in a2 and the global |
| 1477 // object (receiver) in a0. | 1476 // object (receiver) in a0. |
| 1478 __ lw(a0, GlobalObjectOperand()); | 1477 __ lw(a0, GlobalObjectOperand()); |
| 1479 __ li(a2, Operand(var->name())); | 1478 __ li(a2, Operand(var->name())); |
| 1480 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1479 CallLoadIC(CONTEXTUAL); |
| 1481 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 1482 context()->Plug(v0); | 1480 context()->Plug(v0); |
| 1483 break; | 1481 break; |
| 1484 } | 1482 } |
| 1485 | 1483 |
| 1486 case Variable::PARAMETER: | 1484 case Variable::PARAMETER: |
| 1487 case Variable::LOCAL: | 1485 case Variable::LOCAL: |
| 1488 case Variable::CONTEXT: { | 1486 case Variable::CONTEXT: { |
| 1489 Comment cmnt(masm_, var->IsContextSlot() | 1487 Comment cmnt(masm_, var->IsContextSlot() |
| 1490 ? "Context variable" | 1488 ? "Context variable" |
| 1491 : "Stack variable"); | 1489 : "Stack variable"); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1683 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1681 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1684 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1682 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1685 // Fall through. | 1683 // Fall through. |
| 1686 case ObjectLiteral::Property::COMPUTED: | 1684 case ObjectLiteral::Property::COMPUTED: |
| 1687 if (key->value()->IsInternalizedString()) { | 1685 if (key->value()->IsInternalizedString()) { |
| 1688 if (property->emit_store()) { | 1686 if (property->emit_store()) { |
| 1689 VisitForAccumulatorValue(value); | 1687 VisitForAccumulatorValue(value); |
| 1690 __ mov(a0, result_register()); | 1688 __ mov(a0, result_register()); |
| 1691 __ li(a2, Operand(key->value())); | 1689 __ li(a2, Operand(key->value())); |
| 1692 __ lw(a1, MemOperand(sp)); | 1690 __ lw(a1, MemOperand(sp)); |
| 1693 Handle<Code> ic = is_classic_mode() | 1691 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
| 1694 ? isolate()->builtins()->StoreIC_Initialize() | |
| 1695 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 1696 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
| 1697 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1692 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1698 } else { | 1693 } else { |
| 1699 VisitForEffect(value); | 1694 VisitForEffect(value); |
| 1700 } | 1695 } |
| 1701 break; | 1696 break; |
| 1702 } | 1697 } |
| 1703 // Duplicate receiver on stack. | 1698 // Duplicate receiver on stack. |
| 1704 __ lw(a0, MemOperand(sp)); | 1699 __ lw(a0, MemOperand(sp)); |
| 1705 __ push(a0); | 1700 __ push(a0); |
| 1706 VisitForStackValue(key); | 1701 VisitForStackValue(key); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2101 __ bind(&l_call); | 2096 __ bind(&l_call); |
| 2102 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2097 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
| 2103 CallIC(ic); | 2098 CallIC(ic); |
| 2104 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2099 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2105 | 2100 |
| 2106 // if (!result.done) goto l_try; | 2101 // if (!result.done) goto l_try; |
| 2107 __ bind(&l_loop); | 2102 __ bind(&l_loop); |
| 2108 __ mov(a0, v0); | 2103 __ mov(a0, v0); |
| 2109 __ push(a0); // save result | 2104 __ push(a0); // save result |
| 2110 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" | 2105 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" |
| 2111 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2106 CallLoadIC(NOT_CONTEXTUAL); // result.done in v0 |
| 2112 CallIC(done_ic); // result.done in v0 | |
| 2113 __ mov(a0, v0); | 2107 __ mov(a0, v0); |
| 2114 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2108 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2115 CallIC(bool_ic); | 2109 CallIC(bool_ic); |
| 2116 __ Branch(&l_try, eq, v0, Operand(zero_reg)); | 2110 __ Branch(&l_try, eq, v0, Operand(zero_reg)); |
| 2117 | 2111 |
| 2118 // result.value | 2112 // result.value |
| 2119 __ pop(a0); // result | 2113 __ pop(a0); // result |
| 2120 __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" | 2114 __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" |
| 2121 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2115 CallLoadIC(NOT_CONTEXTUAL); // result.value in v0 |
| 2122 CallIC(value_ic); // result.value in v0 | |
| 2123 context()->DropAndPlug(2, v0); // drop iter and g | 2116 context()->DropAndPlug(2, v0); // drop iter and g |
| 2124 break; | 2117 break; |
| 2125 } | 2118 } |
| 2126 } | 2119 } |
| 2127 } | 2120 } |
| 2128 | 2121 |
| 2129 | 2122 |
| 2130 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2123 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2131 Expression *value, | 2124 Expression *value, |
| 2132 JSGeneratorObject::ResumeMode resume_mode) { | 2125 JSGeneratorObject::ResumeMode resume_mode) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2260 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2253 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
| 2261 } | 2254 } |
| 2262 | 2255 |
| 2263 | 2256 |
| 2264 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2257 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2265 SetSourcePosition(prop->position()); | 2258 SetSourcePosition(prop->position()); |
| 2266 Literal* key = prop->key()->AsLiteral(); | 2259 Literal* key = prop->key()->AsLiteral(); |
| 2267 __ mov(a0, result_register()); | 2260 __ mov(a0, result_register()); |
| 2268 __ li(a2, Operand(key->value())); | 2261 __ li(a2, Operand(key->value())); |
| 2269 // Call load IC. It has arguments receiver and property name a0 and a2. | 2262 // Call load IC. It has arguments receiver and property name a0 and a2. |
| 2270 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2263 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2271 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
| 2272 } | 2264 } |
| 2273 | 2265 |
| 2274 | 2266 |
| 2275 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2267 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2276 SetSourcePosition(prop->position()); | 2268 SetSourcePosition(prop->position()); |
| 2277 __ mov(a0, result_register()); | 2269 __ mov(a0, result_register()); |
| 2278 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 2270 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
| 2279 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2271 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2280 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2272 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2281 } | 2273 } |
| 2282 | 2274 |
| 2283 | 2275 |
| 2284 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2276 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2285 Token::Value op, | 2277 Token::Value op, |
| 2286 OverwriteMode mode, | 2278 OverwriteMode mode, |
| 2287 Expression* left_expr, | 2279 Expression* left_expr, |
| 2288 Expression* right_expr) { | 2280 Expression* right_expr) { |
| 2289 Label done, smi_case, stub_call; | 2281 Label done, smi_case, stub_call; |
| 2290 | 2282 |
| 2291 Register scratch1 = a2; | 2283 Register scratch1 = a2; |
| 2292 Register scratch2 = a3; | 2284 Register scratch2 = a3; |
| 2293 | 2285 |
| 2294 // Get the arguments. | 2286 // Get the arguments. |
| 2295 Register left = a1; | 2287 Register left = a1; |
| 2296 Register right = a0; | 2288 Register right = a0; |
| 2297 __ pop(left); | 2289 __ pop(left); |
| 2298 __ mov(a0, result_register()); | 2290 __ mov(a0, result_register()); |
| 2299 | 2291 |
| 2300 // Perform combined smi check on both operands. | 2292 // Perform combined smi check on both operands. |
| 2301 __ Or(scratch1, left, Operand(right)); | 2293 __ Or(scratch1, left, Operand(right)); |
| 2302 STATIC_ASSERT(kSmiTag == 0); | 2294 STATIC_ASSERT(kSmiTag == 0); |
| 2303 JumpPatchSite patch_site(masm_); | 2295 JumpPatchSite patch_site(masm_); |
| 2304 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2296 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 2305 | 2297 |
| 2306 __ bind(&stub_call); | 2298 __ bind(&stub_call); |
| 2307 BinaryOpICStub stub(op, mode); | 2299 BinaryOpICStub stub(op, mode); |
| 2308 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2300 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2309 expr->BinaryOperationFeedbackId()); | 2301 expr->BinaryOperationFeedbackId()); |
| 2310 patch_site.EmitPatchInfo(); | 2302 patch_site.EmitPatchInfo(); |
| 2311 __ jmp(&done); | 2303 __ jmp(&done); |
| 2312 | 2304 |
| 2313 __ bind(&smi_case); | 2305 __ bind(&smi_case); |
| 2314 // Smi case. This code works the same way as the smi-smi case in the type | 2306 // Smi case. This code works the same way as the smi-smi case in the type |
| 2315 // recording binary operation stub, see | 2307 // recording binary operation stub, see |
| 2316 switch (op) { | 2308 switch (op) { |
| 2317 case Token::SAR: | 2309 case Token::SAR: |
| 2318 __ Branch(&stub_call); | 2310 __ Branch(&stub_call); |
| 2319 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2311 __ GetLeastBitsFromSmi(scratch1, right, 5); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 } | 2373 } |
| 2382 | 2374 |
| 2383 | 2375 |
| 2384 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2376 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2385 Token::Value op, | 2377 Token::Value op, |
| 2386 OverwriteMode mode) { | 2378 OverwriteMode mode) { |
| 2387 __ mov(a0, result_register()); | 2379 __ mov(a0, result_register()); |
| 2388 __ pop(a1); | 2380 __ pop(a1); |
| 2389 BinaryOpICStub stub(op, mode); | 2381 BinaryOpICStub stub(op, mode); |
| 2390 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2382 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2391 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2383 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2392 expr->BinaryOperationFeedbackId()); | 2384 expr->BinaryOperationFeedbackId()); |
| 2393 patch_site.EmitPatchInfo(); | 2385 patch_site.EmitPatchInfo(); |
| 2394 context()->Plug(v0); | 2386 context()->Plug(v0); |
| 2395 } | 2387 } |
| 2396 | 2388 |
| 2397 | 2389 |
| 2398 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2390 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2399 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2391 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
| 2400 // ReferenceError' on the left-hand side. | 2392 // ReferenceError' on the left-hand side. |
| 2401 if (!expr->IsValidLeftHandSide()) { | 2393 if (!expr->IsValidLeftHandSide()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2420 EffectContext context(this); | 2412 EffectContext context(this); |
| 2421 EmitVariableAssignment(var, Token::ASSIGN); | 2413 EmitVariableAssignment(var, Token::ASSIGN); |
| 2422 break; | 2414 break; |
| 2423 } | 2415 } |
| 2424 case NAMED_PROPERTY: { | 2416 case NAMED_PROPERTY: { |
| 2425 __ push(result_register()); // Preserve value. | 2417 __ push(result_register()); // Preserve value. |
| 2426 VisitForAccumulatorValue(prop->obj()); | 2418 VisitForAccumulatorValue(prop->obj()); |
| 2427 __ mov(a1, result_register()); | 2419 __ mov(a1, result_register()); |
| 2428 __ pop(a0); // Restore value. | 2420 __ pop(a0); // Restore value. |
| 2429 __ li(a2, Operand(prop->key()->AsLiteral()->value())); | 2421 __ li(a2, Operand(prop->key()->AsLiteral()->value())); |
| 2430 Handle<Code> ic = is_classic_mode() | 2422 CallStoreIC(NOT_CONTEXTUAL); |
| 2431 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2432 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2433 CallIC(ic); | |
| 2434 break; | 2423 break; |
| 2435 } | 2424 } |
| 2436 case KEYED_PROPERTY: { | 2425 case KEYED_PROPERTY: { |
| 2437 __ push(result_register()); // Preserve value. | 2426 __ push(result_register()); // Preserve value. |
| 2438 VisitForStackValue(prop->obj()); | 2427 VisitForStackValue(prop->obj()); |
| 2439 VisitForAccumulatorValue(prop->key()); | 2428 VisitForAccumulatorValue(prop->key()); |
| 2440 __ mov(a1, result_register()); | 2429 __ mov(a1, result_register()); |
| 2441 __ Pop(a0, a2); // a0 = restored value. | 2430 __ Pop(a0, a2); // a0 = restored value. |
| 2442 Handle<Code> ic = is_classic_mode() | 2431 Handle<Code> ic = is_classic_mode() |
| 2443 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2432 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2444 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2433 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2445 CallIC(ic); | 2434 CallIC(ic); |
| 2446 break; | 2435 break; |
| 2447 } | 2436 } |
| 2448 } | 2437 } |
| 2449 context()->Plug(v0); | 2438 context()->Plug(v0); |
| 2450 } | 2439 } |
| 2451 | 2440 |
| 2452 | 2441 |
| 2453 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2442 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2454 Token::Value op) { | 2443 Token::Value op) { |
| 2455 if (var->IsUnallocated()) { | 2444 if (var->IsUnallocated()) { |
| 2456 // Global var, const, or let. | 2445 // Global var, const, or let. |
| 2457 __ mov(a0, result_register()); | 2446 __ mov(a0, result_register()); |
| 2458 __ li(a2, Operand(var->name())); | 2447 __ li(a2, Operand(var->name())); |
| 2459 __ lw(a1, GlobalObjectOperand()); | 2448 __ lw(a1, GlobalObjectOperand()); |
| 2460 Handle<Code> ic = is_classic_mode() | 2449 CallStoreIC(CONTEXTUAL); |
| 2461 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2462 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2463 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 2464 | |
| 2465 } else if (op == Token::INIT_CONST) { | 2450 } else if (op == Token::INIT_CONST) { |
| 2466 // Const initializers need a write barrier. | 2451 // Const initializers need a write barrier. |
| 2467 ASSERT(!var->IsParameter()); // No const parameters. | 2452 ASSERT(!var->IsParameter()); // No const parameters. |
| 2468 if (var->IsStackLocal()) { | 2453 if (var->IsStackLocal()) { |
| 2469 Label skip; | 2454 Label skip; |
| 2470 __ lw(a1, StackOperand(var)); | 2455 __ lw(a1, StackOperand(var)); |
| 2471 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); | 2456 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
| 2472 __ Branch(&skip, ne, a1, Operand(t0)); | 2457 __ Branch(&skip, ne, a1, Operand(t0)); |
| 2473 __ sw(result_register(), StackOperand(var)); | 2458 __ sw(result_register(), StackOperand(var)); |
| 2474 __ bind(&skip); | 2459 __ bind(&skip); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2552 Property* prop = expr->target()->AsProperty(); | 2537 Property* prop = expr->target()->AsProperty(); |
| 2553 ASSERT(prop != NULL); | 2538 ASSERT(prop != NULL); |
| 2554 ASSERT(prop->key()->AsLiteral() != NULL); | 2539 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2555 | 2540 |
| 2556 // Record source code position before IC call. | 2541 // Record source code position before IC call. |
| 2557 SetSourcePosition(expr->position()); | 2542 SetSourcePosition(expr->position()); |
| 2558 __ mov(a0, result_register()); // Load the value. | 2543 __ mov(a0, result_register()); // Load the value. |
| 2559 __ li(a2, Operand(prop->key()->AsLiteral()->value())); | 2544 __ li(a2, Operand(prop->key()->AsLiteral()->value())); |
| 2560 __ pop(a1); | 2545 __ pop(a1); |
| 2561 | 2546 |
| 2562 Handle<Code> ic = is_classic_mode() | 2547 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2563 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2564 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2565 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
| 2566 | 2548 |
| 2567 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2549 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2568 context()->Plug(v0); | 2550 context()->Plug(v0); |
| 2569 } | 2551 } |
| 2570 | 2552 |
| 2571 | 2553 |
| 2572 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2554 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2573 // Assignment to a property, using a keyed store IC. | 2555 // Assignment to a property, using a keyed store IC. |
| 2574 | 2556 |
| 2575 // Record source code position before IC call. | 2557 // Record source code position before IC call. |
| 2576 SetSourcePosition(expr->position()); | 2558 SetSourcePosition(expr->position()); |
| 2577 // Call keyed store IC. | 2559 // Call keyed store IC. |
| 2578 // The arguments are: | 2560 // The arguments are: |
| 2579 // - a0 is the value, | 2561 // - a0 is the value, |
| 2580 // - a1 is the key, | 2562 // - a1 is the key, |
| 2581 // - a2 is the receiver. | 2563 // - a2 is the receiver. |
| 2582 __ mov(a0, result_register()); | 2564 __ mov(a0, result_register()); |
| 2583 __ Pop(a2, a1); // a1 = key. | 2565 __ Pop(a2, a1); // a1 = key. |
| 2584 | 2566 |
| 2585 Handle<Code> ic = is_classic_mode() | 2567 Handle<Code> ic = is_classic_mode() |
| 2586 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2568 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2587 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2569 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2588 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2570 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2589 | 2571 |
| 2590 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2572 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2591 context()->Plug(v0); | 2573 context()->Plug(v0); |
| 2592 } | 2574 } |
| 2593 | 2575 |
| 2594 | 2576 |
| 2595 void FullCodeGenerator::VisitProperty(Property* expr) { | 2577 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2596 Comment cmnt(masm_, "[ Property"); | 2578 Comment cmnt(masm_, "[ Property"); |
| 2597 Expression* key = expr->key(); | 2579 Expression* key = expr->key(); |
| 2598 | 2580 |
| 2599 if (key->IsPropertyName()) { | 2581 if (key->IsPropertyName()) { |
| 2600 VisitForAccumulatorValue(expr->obj()); | 2582 VisitForAccumulatorValue(expr->obj()); |
| 2601 EmitNamedPropertyLoad(expr); | 2583 EmitNamedPropertyLoad(expr); |
| 2602 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2584 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2603 context()->Plug(v0); | 2585 context()->Plug(v0); |
| 2604 } else { | 2586 } else { |
| 2605 VisitForStackValue(expr->obj()); | 2587 VisitForStackValue(expr->obj()); |
| 2606 VisitForAccumulatorValue(expr->key()); | 2588 VisitForAccumulatorValue(expr->key()); |
| 2607 __ pop(a1); | 2589 __ pop(a1); |
| 2608 EmitKeyedPropertyLoad(expr); | 2590 EmitKeyedPropertyLoad(expr); |
| 2609 context()->Plug(v0); | 2591 context()->Plug(v0); |
| 2610 } | 2592 } |
| 2611 } | 2593 } |
| 2612 | 2594 |
| 2613 | 2595 |
| 2614 void FullCodeGenerator::CallIC(Handle<Code> code, | 2596 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2615 RelocInfo::Mode rmode, | 2597 ContextualMode mode, |
| 2616 TypeFeedbackId id) { | 2598 TypeFeedbackId id) { |
| 2617 ic_total_count_++; | 2599 ic_total_count_++; |
| 2618 __ Call(code, rmode, id); | 2600 ASSERT(mode != CONTEXTUAL || id.IsNone()); |
| 2601 __ Call(code, RelocInfo::CODE_TARGET, id); |
| 2619 } | 2602 } |
| 2620 | 2603 |
| 2621 | 2604 |
| 2622 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2605 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 2623 Handle<Object> name, | 2606 Handle<Object> name, |
| 2624 RelocInfo::Mode mode) { | 2607 ContextualMode mode) { |
| 2625 // Code common for calls using the IC. | 2608 // Code common for calls using the IC. |
| 2626 ZoneList<Expression*>* args = expr->arguments(); | 2609 ZoneList<Expression*>* args = expr->arguments(); |
| 2627 int arg_count = args->length(); | 2610 int arg_count = args->length(); |
| 2628 { PreservePositionScope scope(masm()->positions_recorder()); | 2611 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2629 for (int i = 0; i < arg_count; i++) { | 2612 for (int i = 0; i < arg_count; i++) { |
| 2630 VisitForStackValue(args->at(i)); | 2613 VisitForStackValue(args->at(i)); |
| 2631 } | 2614 } |
| 2632 __ li(a2, Operand(name)); | 2615 __ li(a2, Operand(name)); |
| 2633 } | 2616 } |
| 2634 // Record source position for debugger. | 2617 // Record source position for debugger. |
| 2635 SetSourcePosition(expr->position()); | 2618 SetSourcePosition(expr->position()); |
| 2636 // Call the IC initialization code. | 2619 // Call the IC initialization code. |
| 2637 Handle<Code> ic = | 2620 Handle<Code> ic = |
| 2638 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2621 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2639 CallIC(ic, mode, expr->CallFeedbackId()); | 2622 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2623 ? TypeFeedbackId::None() |
| 2624 : expr->CallFeedbackId(); |
| 2625 CallIC(ic, mode, ast_id); |
| 2640 RecordJSReturnSite(expr); | 2626 RecordJSReturnSite(expr); |
| 2641 // Restore context register. | 2627 // Restore context register. |
| 2642 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2628 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2643 context()->Plug(v0); | 2629 context()->Plug(v0); |
| 2644 } | 2630 } |
| 2645 | 2631 |
| 2646 | 2632 |
| 2647 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2633 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2648 Expression* key) { | 2634 Expression* key) { |
| 2649 // Load the key. | 2635 // Load the key. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2662 for (int i = 0; i < arg_count; i++) { | 2648 for (int i = 0; i < arg_count; i++) { |
| 2663 VisitForStackValue(args->at(i)); | 2649 VisitForStackValue(args->at(i)); |
| 2664 } | 2650 } |
| 2665 } | 2651 } |
| 2666 // Record source position for debugger. | 2652 // Record source position for debugger. |
| 2667 SetSourcePosition(expr->position()); | 2653 SetSourcePosition(expr->position()); |
| 2668 // Call the IC initialization code. | 2654 // Call the IC initialization code. |
| 2669 Handle<Code> ic = | 2655 Handle<Code> ic = |
| 2670 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2656 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2671 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2657 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2672 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2658 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
| 2673 RecordJSReturnSite(expr); | 2659 RecordJSReturnSite(expr); |
| 2674 // Restore context register. | 2660 // Restore context register. |
| 2675 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2661 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2676 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2662 context()->DropAndPlug(1, v0); // Drop the key still on the stack. |
| 2677 } | 2663 } |
| 2678 | 2664 |
| 2679 | 2665 |
| 2680 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2666 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2681 // Code common for calls using the call stub. | 2667 // Code common for calls using the call stub. |
| 2682 ZoneList<Expression*>* args = expr->arguments(); | 2668 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2778 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2764 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2779 __ CallStub(&stub); | 2765 __ CallStub(&stub); |
| 2780 RecordJSReturnSite(expr); | 2766 RecordJSReturnSite(expr); |
| 2781 // Restore context register. | 2767 // Restore context register. |
| 2782 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2768 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2783 context()->DropAndPlug(1, v0); | 2769 context()->DropAndPlug(1, v0); |
| 2784 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2770 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 2785 // Push global object as receiver for the call IC. | 2771 // Push global object as receiver for the call IC. |
| 2786 __ lw(a0, GlobalObjectOperand()); | 2772 __ lw(a0, GlobalObjectOperand()); |
| 2787 __ push(a0); | 2773 __ push(a0); |
| 2788 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2774 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
| 2789 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2775 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 2790 // Call to a lookup slot (dynamically introduced variable). | 2776 // Call to a lookup slot (dynamically introduced variable). |
| 2791 Label slow, done; | 2777 Label slow, done; |
| 2792 | 2778 |
| 2793 { PreservePositionScope scope(masm()->positions_recorder()); | 2779 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2794 // Generate code for loading from variables potentially shadowed | 2780 // Generate code for loading from variables potentially shadowed |
| 2795 // by eval-introduced variables. | 2781 // by eval-introduced variables. |
| 2796 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2782 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2797 } | 2783 } |
| 2798 | 2784 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2825 // by LoadContextSlot. That object could be the hole if the | 2811 // by LoadContextSlot. That object could be the hole if the |
| 2826 // receiver is implicitly the global object. | 2812 // receiver is implicitly the global object. |
| 2827 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2813 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2828 } else if (property != NULL) { | 2814 } else if (property != NULL) { |
| 2829 { PreservePositionScope scope(masm()->positions_recorder()); | 2815 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2830 VisitForStackValue(property->obj()); | 2816 VisitForStackValue(property->obj()); |
| 2831 } | 2817 } |
| 2832 if (property->key()->IsPropertyName()) { | 2818 if (property->key()->IsPropertyName()) { |
| 2833 EmitCallWithIC(expr, | 2819 EmitCallWithIC(expr, |
| 2834 property->key()->AsLiteral()->value(), | 2820 property->key()->AsLiteral()->value(), |
| 2835 RelocInfo::CODE_TARGET); | 2821 NOT_CONTEXTUAL); |
| 2836 } else { | 2822 } else { |
| 2837 EmitKeyedCallWithIC(expr, property->key()); | 2823 EmitKeyedCallWithIC(expr, property->key()); |
| 2838 } | 2824 } |
| 2839 } else { | 2825 } else { |
| 2840 // Call to an arbitrary expression not handled specially above. | 2826 // Call to an arbitrary expression not handled specially above. |
| 2841 { PreservePositionScope scope(masm()->positions_recorder()); | 2827 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2842 VisitForStackValue(callee); | 2828 VisitForStackValue(callee); |
| 2843 } | 2829 } |
| 2844 // Load global receiver object. | 2830 // Load global receiver object. |
| 2845 __ lw(a1, GlobalObjectOperand()); | 2831 __ lw(a1, GlobalObjectOperand()); |
| (...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4199 | 4185 |
| 4200 // Push the arguments ("left-to-right"). | 4186 // Push the arguments ("left-to-right"). |
| 4201 int arg_count = args->length(); | 4187 int arg_count = args->length(); |
| 4202 for (int i = 0; i < arg_count; i++) { | 4188 for (int i = 0; i < arg_count; i++) { |
| 4203 VisitForStackValue(args->at(i)); | 4189 VisitForStackValue(args->at(i)); |
| 4204 } | 4190 } |
| 4205 | 4191 |
| 4206 if (expr->is_jsruntime()) { | 4192 if (expr->is_jsruntime()) { |
| 4207 // Call the JS runtime function. | 4193 // Call the JS runtime function. |
| 4208 __ li(a2, Operand(expr->name())); | 4194 __ li(a2, Operand(expr->name())); |
| 4209 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4195 ContextualMode mode = NOT_CONTEXTUAL; |
| 4210 Handle<Code> ic = | 4196 Handle<Code> ic = |
| 4211 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4197 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 4212 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4198 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
| 4213 // Restore context register. | 4199 // Restore context register. |
| 4214 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4200 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4215 } else { | 4201 } else { |
| 4216 // Call the C runtime function. | 4202 // Call the C runtime function. |
| 4217 __ CallRuntime(expr->function(), arg_count); | 4203 __ CallRuntime(expr->function(), arg_count); |
| 4218 } | 4204 } |
| 4219 context()->Plug(v0); | 4205 context()->Plug(v0); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4453 | 4439 |
| 4454 __ bind(&stub_call); | 4440 __ bind(&stub_call); |
| 4455 __ mov(a1, v0); | 4441 __ mov(a1, v0); |
| 4456 __ li(a0, Operand(Smi::FromInt(count_value))); | 4442 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 4457 | 4443 |
| 4458 // Record position before stub call. | 4444 // Record position before stub call. |
| 4459 SetSourcePosition(expr->position()); | 4445 SetSourcePosition(expr->position()); |
| 4460 | 4446 |
| 4461 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); | 4447 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); |
| 4462 CallIC(stub.GetCode(isolate()), | 4448 CallIC(stub.GetCode(isolate()), |
| 4463 RelocInfo::CODE_TARGET, | 4449 NOT_CONTEXTUAL, |
| 4464 expr->CountBinOpFeedbackId()); | 4450 expr->CountBinOpFeedbackId()); |
| 4465 patch_site.EmitPatchInfo(); | 4451 patch_site.EmitPatchInfo(); |
| 4466 __ bind(&done); | 4452 __ bind(&done); |
| 4467 | 4453 |
| 4468 // Store the value returned in v0. | 4454 // Store the value returned in v0. |
| 4469 switch (assign_type) { | 4455 switch (assign_type) { |
| 4470 case VARIABLE: | 4456 case VARIABLE: |
| 4471 if (expr->is_postfix()) { | 4457 if (expr->is_postfix()) { |
| 4472 { EffectContext context(this); | 4458 { EffectContext context(this); |
| 4473 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4459 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4484 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4470 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4485 Token::ASSIGN); | 4471 Token::ASSIGN); |
| 4486 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4472 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4487 context()->Plug(v0); | 4473 context()->Plug(v0); |
| 4488 } | 4474 } |
| 4489 break; | 4475 break; |
| 4490 case NAMED_PROPERTY: { | 4476 case NAMED_PROPERTY: { |
| 4491 __ mov(a0, result_register()); // Value. | 4477 __ mov(a0, result_register()); // Value. |
| 4492 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. | 4478 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. |
| 4493 __ pop(a1); // Receiver. | 4479 __ pop(a1); // Receiver. |
| 4494 Handle<Code> ic = is_classic_mode() | 4480 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4495 ? isolate()->builtins()->StoreIC_Initialize() | |
| 4496 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 4497 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
| 4498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4481 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4499 if (expr->is_postfix()) { | 4482 if (expr->is_postfix()) { |
| 4500 if (!context()->IsEffect()) { | 4483 if (!context()->IsEffect()) { |
| 4501 context()->PlugTOS(); | 4484 context()->PlugTOS(); |
| 4502 } | 4485 } |
| 4503 } else { | 4486 } else { |
| 4504 context()->Plug(v0); | 4487 context()->Plug(v0); |
| 4505 } | 4488 } |
| 4506 break; | 4489 break; |
| 4507 } | 4490 } |
| 4508 case KEYED_PROPERTY: { | 4491 case KEYED_PROPERTY: { |
| 4509 __ mov(a0, result_register()); // Value. | 4492 __ mov(a0, result_register()); // Value. |
| 4510 __ Pop(a2, a1); // a1 = key, a2 = receiver. | 4493 __ Pop(a2, a1); // a1 = key, a2 = receiver. |
| 4511 Handle<Code> ic = is_classic_mode() | 4494 Handle<Code> ic = is_classic_mode() |
| 4512 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4495 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4513 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4496 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4514 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4497 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4515 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4516 if (expr->is_postfix()) { | 4499 if (expr->is_postfix()) { |
| 4517 if (!context()->IsEffect()) { | 4500 if (!context()->IsEffect()) { |
| 4518 context()->PlugTOS(); | 4501 context()->PlugTOS(); |
| 4519 } | 4502 } |
| 4520 } else { | 4503 } else { |
| 4521 context()->Plug(v0); | 4504 context()->Plug(v0); |
| 4522 } | 4505 } |
| 4523 break; | 4506 break; |
| 4524 } | 4507 } |
| 4525 } | 4508 } |
| 4526 } | 4509 } |
| 4527 | 4510 |
| 4528 | 4511 |
| 4529 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4512 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4530 ASSERT(!context()->IsEffect()); | 4513 ASSERT(!context()->IsEffect()); |
| 4531 ASSERT(!context()->IsTest()); | 4514 ASSERT(!context()->IsTest()); |
| 4532 VariableProxy* proxy = expr->AsVariableProxy(); | 4515 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4533 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4516 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4534 Comment cmnt(masm_, "Global variable"); | 4517 Comment cmnt(masm_, "Global variable"); |
| 4535 __ lw(a0, GlobalObjectOperand()); | 4518 __ lw(a0, GlobalObjectOperand()); |
| 4536 __ li(a2, Operand(proxy->name())); | 4519 __ li(a2, Operand(proxy->name())); |
| 4537 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
| 4538 // Use a regular load, not a contextual load, to avoid a reference | 4520 // Use a regular load, not a contextual load, to avoid a reference |
| 4539 // error. | 4521 // error. |
| 4540 CallIC(ic); | 4522 CallLoadIC(NOT_CONTEXTUAL); |
| 4541 PrepareForBailout(expr, TOS_REG); | 4523 PrepareForBailout(expr, TOS_REG); |
| 4542 context()->Plug(v0); | 4524 context()->Plug(v0); |
| 4543 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4525 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4544 Label done, slow; | 4526 Label done, slow; |
| 4545 | 4527 |
| 4546 // Generate code for loading from variables potentially shadowed | 4528 // Generate code for loading from variables potentially shadowed |
| 4547 // by eval-introduced variables. | 4529 // by eval-introduced variables. |
| 4548 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4530 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4549 | 4531 |
| 4550 __ bind(&slow); | 4532 __ bind(&slow); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4690 if (inline_smi_code) { | 4672 if (inline_smi_code) { |
| 4691 Label slow_case; | 4673 Label slow_case; |
| 4692 __ Or(a2, a0, Operand(a1)); | 4674 __ Or(a2, a0, Operand(a1)); |
| 4693 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4675 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
| 4694 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4676 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
| 4695 __ bind(&slow_case); | 4677 __ bind(&slow_case); |
| 4696 } | 4678 } |
| 4697 // Record position and call the compare IC. | 4679 // Record position and call the compare IC. |
| 4698 SetSourcePosition(expr->position()); | 4680 SetSourcePosition(expr->position()); |
| 4699 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4681 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 4700 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4682 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4701 patch_site.EmitPatchInfo(); | 4683 patch_site.EmitPatchInfo(); |
| 4702 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4684 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4703 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4685 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4704 } | 4686 } |
| 4705 } | 4687 } |
| 4706 | 4688 |
| 4707 // Convert the result of the comparison into one expected for this | 4689 // Convert the result of the comparison into one expected for this |
| 4708 // expression's context. | 4690 // expression's context. |
| 4709 context()->Plug(if_true, if_false); | 4691 context()->Plug(if_true, if_false); |
| 4710 } | 4692 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4724 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4706 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4725 __ mov(a0, result_register()); | 4707 __ mov(a0, result_register()); |
| 4726 if (expr->op() == Token::EQ_STRICT) { | 4708 if (expr->op() == Token::EQ_STRICT) { |
| 4727 Heap::RootListIndex nil_value = nil == kNullValue ? | 4709 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4728 Heap::kNullValueRootIndex : | 4710 Heap::kNullValueRootIndex : |
| 4729 Heap::kUndefinedValueRootIndex; | 4711 Heap::kUndefinedValueRootIndex; |
| 4730 __ LoadRoot(a1, nil_value); | 4712 __ LoadRoot(a1, nil_value); |
| 4731 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); | 4713 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); |
| 4732 } else { | 4714 } else { |
| 4733 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4715 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
| 4734 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4716 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4735 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4717 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4736 } | 4718 } |
| 4737 context()->Plug(if_true, if_false); | 4719 context()->Plug(if_true, if_false); |
| 4738 } | 4720 } |
| 4739 | 4721 |
| 4740 | 4722 |
| 4741 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4723 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 4742 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4724 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4743 context()->Plug(v0); | 4725 context()->Plug(v0); |
| 4744 } | 4726 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4962 Assembler::target_address_at(pc_immediate_load_address)) == | 4944 Assembler::target_address_at(pc_immediate_load_address)) == |
| 4963 reinterpret_cast<uint32_t>( | 4945 reinterpret_cast<uint32_t>( |
| 4964 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4946 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4965 return OSR_AFTER_STACK_CHECK; | 4947 return OSR_AFTER_STACK_CHECK; |
| 4966 } | 4948 } |
| 4967 | 4949 |
| 4968 | 4950 |
| 4969 } } // namespace v8::internal | 4951 } } // namespace v8::internal |
| 4970 | 4952 |
| 4971 #endif // V8_TARGET_ARCH_MIPS | 4953 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |