| 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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 if (false_label_ != fall_through_) __ b(false_label_); | 669 if (false_label_ != fall_through_) __ b(false_label_); |
| 670 } | 670 } |
| 671 } | 671 } |
| 672 | 672 |
| 673 | 673 |
| 674 void FullCodeGenerator::DoTest(Expression* condition, | 674 void FullCodeGenerator::DoTest(Expression* condition, |
| 675 Label* if_true, | 675 Label* if_true, |
| 676 Label* if_false, | 676 Label* if_false, |
| 677 Label* fall_through) { | 677 Label* fall_through) { |
| 678 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 678 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
| 679 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 679 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
| 680 __ tst(result_register(), result_register()); | 680 __ tst(result_register(), result_register()); |
| 681 Split(ne, if_true, if_false, fall_through); | 681 Split(ne, if_true, if_false, fall_through); |
| 682 } | 682 } |
| 683 | 683 |
| 684 | 684 |
| 685 void FullCodeGenerator::Split(Condition cond, | 685 void FullCodeGenerator::Split(Condition cond, |
| 686 Label* if_true, | 686 Label* if_true, |
| 687 Label* if_false, | 687 Label* if_false, |
| 688 Label* fall_through) { | 688 Label* fall_through) { |
| 689 if (if_false == fall_through) { | 689 if (if_false == fall_through) { |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 __ cmp(r1, r0); | 1030 __ cmp(r1, r0); |
| 1031 __ b(ne, &next_test); | 1031 __ b(ne, &next_test); |
| 1032 __ Drop(1); // Switch value is no longer needed. | 1032 __ Drop(1); // Switch value is no longer needed. |
| 1033 __ b(clause->body_target()); | 1033 __ b(clause->body_target()); |
| 1034 __ bind(&slow_case); | 1034 __ bind(&slow_case); |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 // Record position before stub call for type feedback. | 1037 // Record position before stub call for type feedback. |
| 1038 SetSourcePosition(clause->position()); | 1038 SetSourcePosition(clause->position()); |
| 1039 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1039 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
| 1040 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 1040 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
| 1041 patch_site.EmitPatchInfo(); | 1041 patch_site.EmitPatchInfo(); |
| 1042 | 1042 |
| 1043 __ cmp(r0, Operand::Zero()); | 1043 __ cmp(r0, Operand::Zero()); |
| 1044 __ b(ne, &next_test); | 1044 __ b(ne, &next_test); |
| 1045 __ Drop(1); // Switch value is no longer needed. | 1045 __ Drop(1); // Switch value is no longer needed. |
| 1046 __ b(clause->body_target()); | 1046 __ b(clause->body_target()); |
| 1047 } | 1047 } |
| 1048 | 1048 |
| 1049 // Discard the test value and jump to the default if present, otherwise to | 1049 // Discard the test value and jump to the default if present, otherwise to |
| 1050 // the end of the statement. | 1050 // the end of the statement. |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1388 __ tst(temp, temp); | 1388 __ tst(temp, temp); |
| 1389 __ b(ne, slow); | 1389 __ b(ne, slow); |
| 1390 // Load next context in chain. | 1390 // Load next context in chain. |
| 1391 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1391 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
| 1392 __ b(&loop); | 1392 __ b(&loop); |
| 1393 __ bind(&fast); | 1393 __ bind(&fast); |
| 1394 } | 1394 } |
| 1395 | 1395 |
| 1396 __ ldr(r0, GlobalObjectOperand()); | 1396 __ ldr(r0, GlobalObjectOperand()); |
| 1397 __ mov(r2, Operand(var->name())); | 1397 __ mov(r2, Operand(var->name())); |
| 1398 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1398 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1399 ? RelocInfo::CODE_TARGET | 1399 ? NOT_CONTEXTUAL |
| 1400 : RelocInfo::CODE_TARGET_CONTEXT; | 1400 : CONTEXTUAL; |
| 1401 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1401 CallLoadIC(mode); |
| 1402 CallIC(ic, mode); | |
| 1403 } | 1402 } |
| 1404 | 1403 |
| 1405 | 1404 |
| 1406 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1405 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1407 Label* slow) { | 1406 Label* slow) { |
| 1408 ASSERT(var->IsContextSlot()); | 1407 ASSERT(var->IsContextSlot()); |
| 1409 Register context = cp; | 1408 Register context = cp; |
| 1410 Register next = r3; | 1409 Register next = r3; |
| 1411 Register temp = r4; | 1410 Register temp = r4; |
| 1412 | 1411 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1475 | 1474 |
| 1476 // Three cases: global variables, lookup variables, and all other types of | 1475 // Three cases: global variables, lookup variables, and all other types of |
| 1477 // variables. | 1476 // variables. |
| 1478 switch (var->location()) { | 1477 switch (var->location()) { |
| 1479 case Variable::UNALLOCATED: { | 1478 case Variable::UNALLOCATED: { |
| 1480 Comment cmnt(masm_, "Global variable"); | 1479 Comment cmnt(masm_, "Global variable"); |
| 1481 // Use inline caching. Variable name is passed in r2 and the global | 1480 // Use inline caching. Variable name is passed in r2 and the global |
| 1482 // object (receiver) in r0. | 1481 // object (receiver) in r0. |
| 1483 __ ldr(r0, GlobalObjectOperand()); | 1482 __ ldr(r0, GlobalObjectOperand()); |
| 1484 __ mov(r2, Operand(var->name())); | 1483 __ mov(r2, Operand(var->name())); |
| 1485 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1484 CallLoadIC(CONTEXTUAL); |
| 1486 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 1487 context()->Plug(r0); | 1485 context()->Plug(r0); |
| 1488 break; | 1486 break; |
| 1489 } | 1487 } |
| 1490 | 1488 |
| 1491 case Variable::PARAMETER: | 1489 case Variable::PARAMETER: |
| 1492 case Variable::LOCAL: | 1490 case Variable::LOCAL: |
| 1493 case Variable::CONTEXT: { | 1491 case Variable::CONTEXT: { |
| 1494 Comment cmnt(masm_, var->IsContextSlot() | 1492 Comment cmnt(masm_, var->IsContextSlot() |
| 1495 ? "Context variable" | 1493 ? "Context variable" |
| 1496 : "Stack variable"); | 1494 : "Stack variable"); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 UNREACHABLE(); | 1683 UNREACHABLE(); |
| 1686 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1684 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1687 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1685 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1688 // Fall through. | 1686 // Fall through. |
| 1689 case ObjectLiteral::Property::COMPUTED: | 1687 case ObjectLiteral::Property::COMPUTED: |
| 1690 if (key->value()->IsInternalizedString()) { | 1688 if (key->value()->IsInternalizedString()) { |
| 1691 if (property->emit_store()) { | 1689 if (property->emit_store()) { |
| 1692 VisitForAccumulatorValue(value); | 1690 VisitForAccumulatorValue(value); |
| 1693 __ mov(r2, Operand(key->value())); | 1691 __ mov(r2, Operand(key->value())); |
| 1694 __ ldr(r1, MemOperand(sp)); | 1692 __ ldr(r1, MemOperand(sp)); |
| 1695 Handle<Code> ic = is_classic_mode() | 1693 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
| 1696 ? isolate()->builtins()->StoreIC_Initialize() | |
| 1697 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 1698 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
| 1699 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1694 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1700 } else { | 1695 } else { |
| 1701 VisitForEffect(value); | 1696 VisitForEffect(value); |
| 1702 } | 1697 } |
| 1703 break; | 1698 break; |
| 1704 } | 1699 } |
| 1705 // Duplicate receiver on stack. | 1700 // Duplicate receiver on stack. |
| 1706 __ ldr(r0, MemOperand(sp)); | 1701 __ ldr(r0, MemOperand(sp)); |
| 1707 __ push(r0); | 1702 __ push(r0); |
| 1708 VisitForStackValue(key); | 1703 VisitForStackValue(key); |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 // result = receiver[f](arg); | 2091 // result = receiver[f](arg); |
| 2097 __ bind(&l_call); | 2092 __ bind(&l_call); |
| 2098 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2093 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
| 2099 CallIC(ic); | 2094 CallIC(ic); |
| 2100 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2095 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2101 | 2096 |
| 2102 // if (!result.done) goto l_try; | 2097 // if (!result.done) goto l_try; |
| 2103 __ bind(&l_loop); | 2098 __ bind(&l_loop); |
| 2104 __ push(r0); // save result | 2099 __ push(r0); // save result |
| 2105 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" | 2100 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" |
| 2106 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2101 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 |
| 2107 CallIC(done_ic); // result.done in r0 | |
| 2108 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2102 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2109 CallIC(bool_ic); | 2103 CallIC(bool_ic); |
| 2110 __ cmp(r0, Operand(0)); | 2104 __ cmp(r0, Operand(0)); |
| 2111 __ b(eq, &l_try); | 2105 __ b(eq, &l_try); |
| 2112 | 2106 |
| 2113 // result.value | 2107 // result.value |
| 2114 __ pop(r0); // result | 2108 __ pop(r0); // result |
| 2115 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" | 2109 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" |
| 2116 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2110 CallLoadIC(NOT_CONTEXTUAL); // result.value in r0 |
| 2117 CallIC(value_ic); // result.value in r0 | |
| 2118 context()->DropAndPlug(2, r0); // drop iter and g | 2111 context()->DropAndPlug(2, r0); // drop iter and g |
| 2119 break; | 2112 break; |
| 2120 } | 2113 } |
| 2121 } | 2114 } |
| 2122 } | 2115 } |
| 2123 | 2116 |
| 2124 | 2117 |
| 2125 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2118 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2126 Expression *value, | 2119 Expression *value, |
| 2127 JSGeneratorObject::ResumeMode resume_mode) { | 2120 JSGeneratorObject::ResumeMode resume_mode) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2256 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, | 2249 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, |
| 2257 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 2250 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2258 } | 2251 } |
| 2259 | 2252 |
| 2260 | 2253 |
| 2261 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2254 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2262 SetSourcePosition(prop->position()); | 2255 SetSourcePosition(prop->position()); |
| 2263 Literal* key = prop->key()->AsLiteral(); | 2256 Literal* key = prop->key()->AsLiteral(); |
| 2264 __ mov(r2, Operand(key->value())); | 2257 __ mov(r2, Operand(key->value())); |
| 2265 // Call load IC. It has arguments receiver and property name r0 and r2. | 2258 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 2266 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2259 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2267 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
| 2268 } | 2260 } |
| 2269 | 2261 |
| 2270 | 2262 |
| 2271 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2263 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2272 SetSourcePosition(prop->position()); | 2264 SetSourcePosition(prop->position()); |
| 2273 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 2265 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 2274 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2266 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2275 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2267 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2276 } | 2268 } |
| 2277 | 2269 |
| 2278 | 2270 |
| 2279 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2271 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2280 Token::Value op, | 2272 Token::Value op, |
| 2281 OverwriteMode mode, | 2273 OverwriteMode mode, |
| 2282 Expression* left_expr, | 2274 Expression* left_expr, |
| 2283 Expression* right_expr) { | 2275 Expression* right_expr) { |
| 2284 Label done, smi_case, stub_call; | 2276 Label done, smi_case, stub_call; |
| 2285 | 2277 |
| 2286 Register scratch1 = r2; | 2278 Register scratch1 = r2; |
| 2287 Register scratch2 = r3; | 2279 Register scratch2 = r3; |
| 2288 | 2280 |
| 2289 // Get the arguments. | 2281 // Get the arguments. |
| 2290 Register left = r1; | 2282 Register left = r1; |
| 2291 Register right = r0; | 2283 Register right = r0; |
| 2292 __ pop(left); | 2284 __ pop(left); |
| 2293 | 2285 |
| 2294 // Perform combined smi check on both operands. | 2286 // Perform combined smi check on both operands. |
| 2295 __ orr(scratch1, left, Operand(right)); | 2287 __ orr(scratch1, left, Operand(right)); |
| 2296 STATIC_ASSERT(kSmiTag == 0); | 2288 STATIC_ASSERT(kSmiTag == 0); |
| 2297 JumpPatchSite patch_site(masm_); | 2289 JumpPatchSite patch_site(masm_); |
| 2298 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2290 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 2299 | 2291 |
| 2300 __ bind(&stub_call); | 2292 __ bind(&stub_call); |
| 2301 BinaryOpICStub stub(op, mode); | 2293 BinaryOpICStub stub(op, mode); |
| 2302 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2294 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2303 expr->BinaryOperationFeedbackId()); | 2295 expr->BinaryOperationFeedbackId()); |
| 2304 patch_site.EmitPatchInfo(); | 2296 patch_site.EmitPatchInfo(); |
| 2305 __ jmp(&done); | 2297 __ jmp(&done); |
| 2306 | 2298 |
| 2307 __ bind(&smi_case); | 2299 __ bind(&smi_case); |
| 2308 // Smi case. This code works the same way as the smi-smi case in the type | 2300 // Smi case. This code works the same way as the smi-smi case in the type |
| 2309 // recording binary operation stub, see | 2301 // recording binary operation stub, see |
| 2310 switch (op) { | 2302 switch (op) { |
| 2311 case Token::SAR: | 2303 case Token::SAR: |
| 2312 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2304 __ GetLeastBitsFromSmi(scratch1, right, 5); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 context()->Plug(r0); | 2362 context()->Plug(r0); |
| 2371 } | 2363 } |
| 2372 | 2364 |
| 2373 | 2365 |
| 2374 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2366 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2375 Token::Value op, | 2367 Token::Value op, |
| 2376 OverwriteMode mode) { | 2368 OverwriteMode mode) { |
| 2377 __ pop(r1); | 2369 __ pop(r1); |
| 2378 BinaryOpICStub stub(op, mode); | 2370 BinaryOpICStub stub(op, mode); |
| 2379 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2371 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2380 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2372 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2381 expr->BinaryOperationFeedbackId()); | 2373 expr->BinaryOperationFeedbackId()); |
| 2382 patch_site.EmitPatchInfo(); | 2374 patch_site.EmitPatchInfo(); |
| 2383 context()->Plug(r0); | 2375 context()->Plug(r0); |
| 2384 } | 2376 } |
| 2385 | 2377 |
| 2386 | 2378 |
| 2387 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2379 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2388 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2380 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
| 2389 // ReferenceError' on the left-hand side. | 2381 // ReferenceError' on the left-hand side. |
| 2390 if (!expr->IsValidLeftHandSide()) { | 2382 if (!expr->IsValidLeftHandSide()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2409 EffectContext context(this); | 2401 EffectContext context(this); |
| 2410 EmitVariableAssignment(var, Token::ASSIGN); | 2402 EmitVariableAssignment(var, Token::ASSIGN); |
| 2411 break; | 2403 break; |
| 2412 } | 2404 } |
| 2413 case NAMED_PROPERTY: { | 2405 case NAMED_PROPERTY: { |
| 2414 __ push(r0); // Preserve value. | 2406 __ push(r0); // Preserve value. |
| 2415 VisitForAccumulatorValue(prop->obj()); | 2407 VisitForAccumulatorValue(prop->obj()); |
| 2416 __ mov(r1, r0); | 2408 __ mov(r1, r0); |
| 2417 __ pop(r0); // Restore value. | 2409 __ pop(r0); // Restore value. |
| 2418 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 2410 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
| 2419 Handle<Code> ic = is_classic_mode() | 2411 CallStoreIC(NOT_CONTEXTUAL); |
| 2420 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2421 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2422 CallIC(ic); | |
| 2423 break; | 2412 break; |
| 2424 } | 2413 } |
| 2425 case KEYED_PROPERTY: { | 2414 case KEYED_PROPERTY: { |
| 2426 __ push(r0); // Preserve value. | 2415 __ push(r0); // Preserve value. |
| 2427 VisitForStackValue(prop->obj()); | 2416 VisitForStackValue(prop->obj()); |
| 2428 VisitForAccumulatorValue(prop->key()); | 2417 VisitForAccumulatorValue(prop->key()); |
| 2429 __ mov(r1, r0); | 2418 __ mov(r1, r0); |
| 2430 __ Pop(r0, r2); // r0 = restored value. | 2419 __ Pop(r0, r2); // r0 = restored value. |
| 2431 Handle<Code> ic = is_classic_mode() | 2420 Handle<Code> ic = is_classic_mode() |
| 2432 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2421 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2433 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2422 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2434 CallIC(ic); | 2423 CallIC(ic); |
| 2435 break; | 2424 break; |
| 2436 } | 2425 } |
| 2437 } | 2426 } |
| 2438 context()->Plug(r0); | 2427 context()->Plug(r0); |
| 2439 } | 2428 } |
| 2440 | 2429 |
| 2441 | 2430 |
| 2442 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2431 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2443 Token::Value op) { | 2432 Token::Value op) { |
| 2444 if (var->IsUnallocated()) { | 2433 if (var->IsUnallocated()) { |
| 2445 // Global var, const, or let. | 2434 // Global var, const, or let. |
| 2446 __ mov(r2, Operand(var->name())); | 2435 __ mov(r2, Operand(var->name())); |
| 2447 __ ldr(r1, GlobalObjectOperand()); | 2436 __ ldr(r1, GlobalObjectOperand()); |
| 2448 Handle<Code> ic = is_classic_mode() | 2437 CallStoreIC(CONTEXTUAL); |
| 2449 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2450 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2451 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 2452 | |
| 2453 } else if (op == Token::INIT_CONST) { | 2438 } else if (op == Token::INIT_CONST) { |
| 2454 // Const initializers need a write barrier. | 2439 // Const initializers need a write barrier. |
| 2455 ASSERT(!var->IsParameter()); // No const parameters. | 2440 ASSERT(!var->IsParameter()); // No const parameters. |
| 2456 if (var->IsStackLocal()) { | 2441 if (var->IsStackLocal()) { |
| 2457 Label skip; | 2442 Label skip; |
| 2458 __ ldr(r1, StackOperand(var)); | 2443 __ ldr(r1, StackOperand(var)); |
| 2459 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); | 2444 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); |
| 2460 __ b(ne, &skip); | 2445 __ b(ne, &skip); |
| 2461 __ str(result_register(), StackOperand(var)); | 2446 __ str(result_register(), StackOperand(var)); |
| 2462 __ bind(&skip); | 2447 __ bind(&skip); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2539 // Assignment to a property, using a named store IC. | 2524 // Assignment to a property, using a named store IC. |
| 2540 Property* prop = expr->target()->AsProperty(); | 2525 Property* prop = expr->target()->AsProperty(); |
| 2541 ASSERT(prop != NULL); | 2526 ASSERT(prop != NULL); |
| 2542 ASSERT(prop->key()->AsLiteral() != NULL); | 2527 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2543 | 2528 |
| 2544 // Record source code position before IC call. | 2529 // Record source code position before IC call. |
| 2545 SetSourcePosition(expr->position()); | 2530 SetSourcePosition(expr->position()); |
| 2546 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 2531 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
| 2547 __ pop(r1); | 2532 __ pop(r1); |
| 2548 | 2533 |
| 2549 Handle<Code> ic = is_classic_mode() | 2534 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2550 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2551 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2552 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
| 2553 | 2535 |
| 2554 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2536 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2555 context()->Plug(r0); | 2537 context()->Plug(r0); |
| 2556 } | 2538 } |
| 2557 | 2539 |
| 2558 | 2540 |
| 2559 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2541 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2560 // Assignment to a property, using a keyed store IC. | 2542 // Assignment to a property, using a keyed store IC. |
| 2561 | 2543 |
| 2562 // Record source code position before IC call. | 2544 // Record source code position before IC call. |
| 2563 SetSourcePosition(expr->position()); | 2545 SetSourcePosition(expr->position()); |
| 2564 __ Pop(r2, r1); // r1 = key. | 2546 __ Pop(r2, r1); // r1 = key. |
| 2565 | 2547 |
| 2566 Handle<Code> ic = is_classic_mode() | 2548 Handle<Code> ic = is_classic_mode() |
| 2567 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2549 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2568 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2550 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2569 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2551 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2570 | 2552 |
| 2571 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2553 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2572 context()->Plug(r0); | 2554 context()->Plug(r0); |
| 2573 } | 2555 } |
| 2574 | 2556 |
| 2575 | 2557 |
| 2576 void FullCodeGenerator::VisitProperty(Property* expr) { | 2558 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2577 Comment cmnt(masm_, "[ Property"); | 2559 Comment cmnt(masm_, "[ Property"); |
| 2578 Expression* key = expr->key(); | 2560 Expression* key = expr->key(); |
| 2579 | 2561 |
| 2580 if (key->IsPropertyName()) { | 2562 if (key->IsPropertyName()) { |
| 2581 VisitForAccumulatorValue(expr->obj()); | 2563 VisitForAccumulatorValue(expr->obj()); |
| 2582 EmitNamedPropertyLoad(expr); | 2564 EmitNamedPropertyLoad(expr); |
| 2583 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2565 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2584 context()->Plug(r0); | 2566 context()->Plug(r0); |
| 2585 } else { | 2567 } else { |
| 2586 VisitForStackValue(expr->obj()); | 2568 VisitForStackValue(expr->obj()); |
| 2587 VisitForAccumulatorValue(expr->key()); | 2569 VisitForAccumulatorValue(expr->key()); |
| 2588 __ pop(r1); | 2570 __ pop(r1); |
| 2589 EmitKeyedPropertyLoad(expr); | 2571 EmitKeyedPropertyLoad(expr); |
| 2590 context()->Plug(r0); | 2572 context()->Plug(r0); |
| 2591 } | 2573 } |
| 2592 } | 2574 } |
| 2593 | 2575 |
| 2594 | 2576 |
| 2595 void FullCodeGenerator::CallIC(Handle<Code> code, | 2577 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2596 RelocInfo::Mode rmode, | 2578 ContextualMode mode, |
| 2597 TypeFeedbackId ast_id) { | 2579 TypeFeedbackId ast_id) { |
| 2598 ic_total_count_++; | 2580 ic_total_count_++; |
| 2599 // All calls must have a predictable size in full-codegen code to ensure that | 2581 // All calls must have a predictable size in full-codegen code to ensure that |
| 2600 // the debugger can patch them correctly. | 2582 // the debugger can patch them correctly. |
| 2601 __ Call(code, rmode, ast_id, al, NEVER_INLINE_TARGET_ADDRESS); | 2583 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
| 2584 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, |
| 2585 NEVER_INLINE_TARGET_ADDRESS); |
| 2602 } | 2586 } |
| 2603 | 2587 |
| 2604 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2588 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 2605 Handle<Object> name, | 2589 Handle<Object> name, |
| 2606 RelocInfo::Mode mode) { | 2590 ContextualMode mode) { |
| 2607 // Code common for calls using the IC. | 2591 // Code common for calls using the IC. |
| 2608 ZoneList<Expression*>* args = expr->arguments(); | 2592 ZoneList<Expression*>* args = expr->arguments(); |
| 2609 int arg_count = args->length(); | 2593 int arg_count = args->length(); |
| 2610 { PreservePositionScope scope(masm()->positions_recorder()); | 2594 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2611 for (int i = 0; i < arg_count; i++) { | 2595 for (int i = 0; i < arg_count; i++) { |
| 2612 VisitForStackValue(args->at(i)); | 2596 VisitForStackValue(args->at(i)); |
| 2613 } | 2597 } |
| 2614 __ mov(r2, Operand(name)); | 2598 __ mov(r2, Operand(name)); |
| 2615 } | 2599 } |
| 2616 // Record source position for debugger. | 2600 // Record source position for debugger. |
| 2617 SetSourcePosition(expr->position()); | 2601 SetSourcePosition(expr->position()); |
| 2618 // Call the IC initialization code. | 2602 // Call the IC initialization code. |
| 2619 Handle<Code> ic = | 2603 Handle<Code> ic = |
| 2620 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2604 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2621 CallIC(ic, mode, expr->CallFeedbackId()); | 2605 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2606 ? TypeFeedbackId::None() |
| 2607 : expr->CallFeedbackId(); |
| 2608 CallIC(ic, mode, ast_id); |
| 2622 RecordJSReturnSite(expr); | 2609 RecordJSReturnSite(expr); |
| 2623 // Restore context register. | 2610 // Restore context register. |
| 2624 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2611 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2625 context()->Plug(r0); | 2612 context()->Plug(r0); |
| 2626 } | 2613 } |
| 2627 | 2614 |
| 2628 | 2615 |
| 2629 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2616 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2630 Expression* key) { | 2617 Expression* key) { |
| 2631 // Load the key. | 2618 // Load the key. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2644 for (int i = 0; i < arg_count; i++) { | 2631 for (int i = 0; i < arg_count; i++) { |
| 2645 VisitForStackValue(args->at(i)); | 2632 VisitForStackValue(args->at(i)); |
| 2646 } | 2633 } |
| 2647 } | 2634 } |
| 2648 // Record source position for debugger. | 2635 // Record source position for debugger. |
| 2649 SetSourcePosition(expr->position()); | 2636 SetSourcePosition(expr->position()); |
| 2650 // Call the IC initialization code. | 2637 // Call the IC initialization code. |
| 2651 Handle<Code> ic = | 2638 Handle<Code> ic = |
| 2652 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2639 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2653 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2640 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2654 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2641 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
| 2655 RecordJSReturnSite(expr); | 2642 RecordJSReturnSite(expr); |
| 2656 // Restore context register. | 2643 // Restore context register. |
| 2657 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2644 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2658 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2645 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
| 2659 } | 2646 } |
| 2660 | 2647 |
| 2661 | 2648 |
| 2662 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2649 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2663 // Code common for calls using the call stub. | 2650 // Code common for calls using the call stub. |
| 2664 ZoneList<Expression*>* args = expr->arguments(); | 2651 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2761 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2748 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2762 __ CallStub(&stub); | 2749 __ CallStub(&stub); |
| 2763 RecordJSReturnSite(expr); | 2750 RecordJSReturnSite(expr); |
| 2764 // Restore context register. | 2751 // Restore context register. |
| 2765 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2752 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2766 context()->DropAndPlug(1, r0); | 2753 context()->DropAndPlug(1, r0); |
| 2767 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2754 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 2768 // Push global object as receiver for the call IC. | 2755 // Push global object as receiver for the call IC. |
| 2769 __ ldr(r0, GlobalObjectOperand()); | 2756 __ ldr(r0, GlobalObjectOperand()); |
| 2770 __ push(r0); | 2757 __ push(r0); |
| 2771 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2758 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
| 2772 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2759 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 2773 // Call to a lookup slot (dynamically introduced variable). | 2760 // Call to a lookup slot (dynamically introduced variable). |
| 2774 Label slow, done; | 2761 Label slow, done; |
| 2775 | 2762 |
| 2776 { PreservePositionScope scope(masm()->positions_recorder()); | 2763 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2777 // Generate code for loading from variables potentially shadowed | 2764 // Generate code for loading from variables potentially shadowed |
| 2778 // by eval-introduced variables. | 2765 // by eval-introduced variables. |
| 2779 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2766 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2780 } | 2767 } |
| 2781 | 2768 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2808 // by LoadContextSlot. That object could be the hole if the | 2795 // by LoadContextSlot. That object could be the hole if the |
| 2809 // receiver is implicitly the global object. | 2796 // receiver is implicitly the global object. |
| 2810 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2797 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2811 } else if (property != NULL) { | 2798 } else if (property != NULL) { |
| 2812 { PreservePositionScope scope(masm()->positions_recorder()); | 2799 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2813 VisitForStackValue(property->obj()); | 2800 VisitForStackValue(property->obj()); |
| 2814 } | 2801 } |
| 2815 if (property->key()->IsPropertyName()) { | 2802 if (property->key()->IsPropertyName()) { |
| 2816 EmitCallWithIC(expr, | 2803 EmitCallWithIC(expr, |
| 2817 property->key()->AsLiteral()->value(), | 2804 property->key()->AsLiteral()->value(), |
| 2818 RelocInfo::CODE_TARGET); | 2805 NOT_CONTEXTUAL); |
| 2819 } else { | 2806 } else { |
| 2820 EmitKeyedCallWithIC(expr, property->key()); | 2807 EmitKeyedCallWithIC(expr, property->key()); |
| 2821 } | 2808 } |
| 2822 } else { | 2809 } else { |
| 2823 // Call to an arbitrary expression not handled specially above. | 2810 // Call to an arbitrary expression not handled specially above. |
| 2824 { PreservePositionScope scope(masm()->positions_recorder()); | 2811 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2825 VisitForStackValue(callee); | 2812 VisitForStackValue(callee); |
| 2826 } | 2813 } |
| 2827 // Load global receiver object. | 2814 // Load global receiver object. |
| 2828 __ ldr(r1, GlobalObjectOperand()); | 2815 __ ldr(r1, GlobalObjectOperand()); |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4159 | 4146 |
| 4160 // Push the arguments ("left-to-right"). | 4147 // Push the arguments ("left-to-right"). |
| 4161 int arg_count = args->length(); | 4148 int arg_count = args->length(); |
| 4162 for (int i = 0; i < arg_count; i++) { | 4149 for (int i = 0; i < arg_count; i++) { |
| 4163 VisitForStackValue(args->at(i)); | 4150 VisitForStackValue(args->at(i)); |
| 4164 } | 4151 } |
| 4165 | 4152 |
| 4166 if (expr->is_jsruntime()) { | 4153 if (expr->is_jsruntime()) { |
| 4167 // Call the JS runtime function. | 4154 // Call the JS runtime function. |
| 4168 __ mov(r2, Operand(expr->name())); | 4155 __ mov(r2, Operand(expr->name())); |
| 4169 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4156 ContextualMode mode = NOT_CONTEXTUAL; |
| 4170 Handle<Code> ic = | 4157 Handle<Code> ic = |
| 4171 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4158 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 4172 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4159 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
| 4173 // Restore context register. | 4160 // Restore context register. |
| 4174 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4161 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4175 } else { | 4162 } else { |
| 4176 // Call the C runtime function. | 4163 // Call the C runtime function. |
| 4177 __ CallRuntime(expr->function(), arg_count); | 4164 __ CallRuntime(expr->function(), arg_count); |
| 4178 } | 4165 } |
| 4179 context()->Plug(r0); | 4166 context()->Plug(r0); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4410 | 4397 |
| 4411 __ bind(&stub_call); | 4398 __ bind(&stub_call); |
| 4412 __ mov(r1, r0); | 4399 __ mov(r1, r0); |
| 4413 __ mov(r0, Operand(Smi::FromInt(count_value))); | 4400 __ mov(r0, Operand(Smi::FromInt(count_value))); |
| 4414 | 4401 |
| 4415 // Record position before stub call. | 4402 // Record position before stub call. |
| 4416 SetSourcePosition(expr->position()); | 4403 SetSourcePosition(expr->position()); |
| 4417 | 4404 |
| 4418 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); | 4405 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); |
| 4419 CallIC(stub.GetCode(isolate()), | 4406 CallIC(stub.GetCode(isolate()), |
| 4420 RelocInfo::CODE_TARGET, | 4407 NOT_CONTEXTUAL, |
| 4421 expr->CountBinOpFeedbackId()); | 4408 expr->CountBinOpFeedbackId()); |
| 4422 patch_site.EmitPatchInfo(); | 4409 patch_site.EmitPatchInfo(); |
| 4423 __ bind(&done); | 4410 __ bind(&done); |
| 4424 | 4411 |
| 4425 // Store the value returned in r0. | 4412 // Store the value returned in r0. |
| 4426 switch (assign_type) { | 4413 switch (assign_type) { |
| 4427 case VARIABLE: | 4414 case VARIABLE: |
| 4428 if (expr->is_postfix()) { | 4415 if (expr->is_postfix()) { |
| 4429 { EffectContext context(this); | 4416 { EffectContext context(this); |
| 4430 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4417 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4431 Token::ASSIGN); | 4418 Token::ASSIGN); |
| 4432 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4419 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4433 context.Plug(r0); | 4420 context.Plug(r0); |
| 4434 } | 4421 } |
| 4435 // For all contexts except EffectConstant We have the result on | 4422 // For all contexts except EffectConstant We have the result on |
| 4436 // top of the stack. | 4423 // top of the stack. |
| 4437 if (!context()->IsEffect()) { | 4424 if (!context()->IsEffect()) { |
| 4438 context()->PlugTOS(); | 4425 context()->PlugTOS(); |
| 4439 } | 4426 } |
| 4440 } else { | 4427 } else { |
| 4441 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4428 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4442 Token::ASSIGN); | 4429 Token::ASSIGN); |
| 4443 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4430 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4444 context()->Plug(r0); | 4431 context()->Plug(r0); |
| 4445 } | 4432 } |
| 4446 break; | 4433 break; |
| 4447 case NAMED_PROPERTY: { | 4434 case NAMED_PROPERTY: { |
| 4448 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 4435 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
| 4449 __ pop(r1); | 4436 __ pop(r1); |
| 4450 Handle<Code> ic = is_classic_mode() | 4437 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4451 ? isolate()->builtins()->StoreIC_Initialize() | |
| 4452 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 4453 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
| 4454 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4438 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4455 if (expr->is_postfix()) { | 4439 if (expr->is_postfix()) { |
| 4456 if (!context()->IsEffect()) { | 4440 if (!context()->IsEffect()) { |
| 4457 context()->PlugTOS(); | 4441 context()->PlugTOS(); |
| 4458 } | 4442 } |
| 4459 } else { | 4443 } else { |
| 4460 context()->Plug(r0); | 4444 context()->Plug(r0); |
| 4461 } | 4445 } |
| 4462 break; | 4446 break; |
| 4463 } | 4447 } |
| 4464 case KEYED_PROPERTY: { | 4448 case KEYED_PROPERTY: { |
| 4465 __ Pop(r2, r1); // r1 = key. r2 = receiver. | 4449 __ Pop(r2, r1); // r1 = key. r2 = receiver. |
| 4466 Handle<Code> ic = is_classic_mode() | 4450 Handle<Code> ic = is_classic_mode() |
| 4467 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4451 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4468 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4452 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4469 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4453 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4470 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4454 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4471 if (expr->is_postfix()) { | 4455 if (expr->is_postfix()) { |
| 4472 if (!context()->IsEffect()) { | 4456 if (!context()->IsEffect()) { |
| 4473 context()->PlugTOS(); | 4457 context()->PlugTOS(); |
| 4474 } | 4458 } |
| 4475 } else { | 4459 } else { |
| 4476 context()->Plug(r0); | 4460 context()->Plug(r0); |
| 4477 } | 4461 } |
| 4478 break; | 4462 break; |
| 4479 } | 4463 } |
| 4480 } | 4464 } |
| 4481 } | 4465 } |
| 4482 | 4466 |
| 4483 | 4467 |
| 4484 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4468 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4485 ASSERT(!context()->IsEffect()); | 4469 ASSERT(!context()->IsEffect()); |
| 4486 ASSERT(!context()->IsTest()); | 4470 ASSERT(!context()->IsTest()); |
| 4487 VariableProxy* proxy = expr->AsVariableProxy(); | 4471 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4488 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4472 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4489 Comment cmnt(masm_, "Global variable"); | 4473 Comment cmnt(masm_, "Global variable"); |
| 4490 __ ldr(r0, GlobalObjectOperand()); | 4474 __ ldr(r0, GlobalObjectOperand()); |
| 4491 __ mov(r2, Operand(proxy->name())); | 4475 __ mov(r2, Operand(proxy->name())); |
| 4492 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
| 4493 // Use a regular load, not a contextual load, to avoid a reference | 4476 // Use a regular load, not a contextual load, to avoid a reference |
| 4494 // error. | 4477 // error. |
| 4495 CallIC(ic); | 4478 CallLoadIC(NOT_CONTEXTUAL); |
| 4496 PrepareForBailout(expr, TOS_REG); | 4479 PrepareForBailout(expr, TOS_REG); |
| 4497 context()->Plug(r0); | 4480 context()->Plug(r0); |
| 4498 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4481 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4499 Label done, slow; | 4482 Label done, slow; |
| 4500 | 4483 |
| 4501 // Generate code for loading from variables potentially shadowed | 4484 // Generate code for loading from variables potentially shadowed |
| 4502 // by eval-introduced variables. | 4485 // by eval-introduced variables. |
| 4503 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4486 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4504 | 4487 |
| 4505 __ bind(&slow); | 4488 __ bind(&slow); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4650 __ orr(r2, r0, Operand(r1)); | 4633 __ orr(r2, r0, Operand(r1)); |
| 4651 patch_site.EmitJumpIfNotSmi(r2, &slow_case); | 4634 patch_site.EmitJumpIfNotSmi(r2, &slow_case); |
| 4652 __ cmp(r1, r0); | 4635 __ cmp(r1, r0); |
| 4653 Split(cond, if_true, if_false, NULL); | 4636 Split(cond, if_true, if_false, NULL); |
| 4654 __ bind(&slow_case); | 4637 __ bind(&slow_case); |
| 4655 } | 4638 } |
| 4656 | 4639 |
| 4657 // Record position and call the compare IC. | 4640 // Record position and call the compare IC. |
| 4658 SetSourcePosition(expr->position()); | 4641 SetSourcePosition(expr->position()); |
| 4659 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4642 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 4660 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4643 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4661 patch_site.EmitPatchInfo(); | 4644 patch_site.EmitPatchInfo(); |
| 4662 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4645 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4663 __ cmp(r0, Operand::Zero()); | 4646 __ cmp(r0, Operand::Zero()); |
| 4664 Split(cond, if_true, if_false, fall_through); | 4647 Split(cond, if_true, if_false, fall_through); |
| 4665 } | 4648 } |
| 4666 } | 4649 } |
| 4667 | 4650 |
| 4668 // Convert the result of the comparison into one expected for this | 4651 // Convert the result of the comparison into one expected for this |
| 4669 // expression's context. | 4652 // expression's context. |
| 4670 context()->Plug(if_true, if_false); | 4653 context()->Plug(if_true, if_false); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4685 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4668 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4686 if (expr->op() == Token::EQ_STRICT) { | 4669 if (expr->op() == Token::EQ_STRICT) { |
| 4687 Heap::RootListIndex nil_value = nil == kNullValue ? | 4670 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4688 Heap::kNullValueRootIndex : | 4671 Heap::kNullValueRootIndex : |
| 4689 Heap::kUndefinedValueRootIndex; | 4672 Heap::kUndefinedValueRootIndex; |
| 4690 __ LoadRoot(r1, nil_value); | 4673 __ LoadRoot(r1, nil_value); |
| 4691 __ cmp(r0, r1); | 4674 __ cmp(r0, r1); |
| 4692 Split(eq, if_true, if_false, fall_through); | 4675 Split(eq, if_true, if_false, fall_through); |
| 4693 } else { | 4676 } else { |
| 4694 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4677 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
| 4695 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4678 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4696 __ cmp(r0, Operand(0)); | 4679 __ cmp(r0, Operand(0)); |
| 4697 Split(ne, if_true, if_false, fall_through); | 4680 Split(ne, if_true, if_false, fall_through); |
| 4698 } | 4681 } |
| 4699 context()->Plug(if_true, if_false); | 4682 context()->Plug(if_true, if_false); |
| 4700 } | 4683 } |
| 4701 | 4684 |
| 4702 | 4685 |
| 4703 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4686 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 4704 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4687 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4705 context()->Plug(r0); | 4688 context()->Plug(r0); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4928 ASSERT(Memory::uint32_at(interrupt_address_pointer) == | 4911 ASSERT(Memory::uint32_at(interrupt_address_pointer) == |
| 4929 reinterpret_cast<uint32_t>( | 4912 reinterpret_cast<uint32_t>( |
| 4930 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4913 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4931 return OSR_AFTER_STACK_CHECK; | 4914 return OSR_AFTER_STACK_CHECK; |
| 4932 } | 4915 } |
| 4933 | 4916 |
| 4934 | 4917 |
| 4935 } } // namespace v8::internal | 4918 } } // namespace v8::internal |
| 4936 | 4919 |
| 4937 #endif // V8_TARGET_ARCH_ARM | 4920 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |