| 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 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 if (false_label_ != fall_through_) __ jmp(false_label_); | 623 if (false_label_ != fall_through_) __ jmp(false_label_); |
| 624 } | 624 } |
| 625 } | 625 } |
| 626 | 626 |
| 627 | 627 |
| 628 void FullCodeGenerator::DoTest(Expression* condition, | 628 void FullCodeGenerator::DoTest(Expression* condition, |
| 629 Label* if_true, | 629 Label* if_true, |
| 630 Label* if_false, | 630 Label* if_false, |
| 631 Label* fall_through) { | 631 Label* fall_through) { |
| 632 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 632 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
| 633 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 633 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
| 634 __ testq(result_register(), result_register()); | 634 __ testq(result_register(), result_register()); |
| 635 // The stub returns nonzero for true. | 635 // The stub returns nonzero for true. |
| 636 Split(not_zero, if_true, if_false, fall_through); | 636 Split(not_zero, if_true, if_false, fall_through); |
| 637 } | 637 } |
| 638 | 638 |
| 639 | 639 |
| 640 void FullCodeGenerator::Split(Condition cc, | 640 void FullCodeGenerator::Split(Condition cc, |
| 641 Label* if_true, | 641 Label* if_true, |
| 642 Label* if_false, | 642 Label* if_false, |
| 643 Label* fall_through) { | 643 Label* fall_through) { |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 __ cmpq(rdx, rax); | 976 __ cmpq(rdx, rax); |
| 977 __ j(not_equal, &next_test); | 977 __ j(not_equal, &next_test); |
| 978 __ Drop(1); // Switch value is no longer needed. | 978 __ Drop(1); // Switch value is no longer needed. |
| 979 __ jmp(clause->body_target()); | 979 __ jmp(clause->body_target()); |
| 980 __ bind(&slow_case); | 980 __ bind(&slow_case); |
| 981 } | 981 } |
| 982 | 982 |
| 983 // Record position before stub call for type feedback. | 983 // Record position before stub call for type feedback. |
| 984 SetSourcePosition(clause->position()); | 984 SetSourcePosition(clause->position()); |
| 985 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 985 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
| 986 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 986 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
| 987 patch_site.EmitPatchInfo(); | 987 patch_site.EmitPatchInfo(); |
| 988 | 988 |
| 989 __ testq(rax, rax); | 989 __ testq(rax, rax); |
| 990 __ j(not_equal, &next_test); | 990 __ j(not_equal, &next_test); |
| 991 __ Drop(1); // Switch value is no longer needed. | 991 __ Drop(1); // Switch value is no longer needed. |
| 992 __ jmp(clause->body_target()); | 992 __ jmp(clause->body_target()); |
| 993 } | 993 } |
| 994 | 994 |
| 995 // Discard the test value and jump to the default if present, otherwise to | 995 // Discard the test value and jump to the default if present, otherwise to |
| 996 // the end of the statement. | 996 // the end of the statement. |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1337 // Load next context in chain. | 1337 // Load next context in chain. |
| 1338 __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1338 __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
| 1339 __ jmp(&next); | 1339 __ jmp(&next); |
| 1340 __ bind(&fast); | 1340 __ bind(&fast); |
| 1341 } | 1341 } |
| 1342 | 1342 |
| 1343 // All extension objects were empty and it is safe to use a global | 1343 // All extension objects were empty and it is safe to use a global |
| 1344 // load IC call. | 1344 // load IC call. |
| 1345 __ movq(rax, GlobalObjectOperand()); | 1345 __ movq(rax, GlobalObjectOperand()); |
| 1346 __ Move(rcx, var->name()); | 1346 __ Move(rcx, var->name()); |
| 1347 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1347 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1348 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1348 ? NOT_CONTEXTUAL |
| 1349 ? RelocInfo::CODE_TARGET | 1349 : CONTEXTUAL; |
| 1350 : RelocInfo::CODE_TARGET_CONTEXT; | 1350 CallLoadIC(mode); |
| 1351 CallIC(ic, mode); | |
| 1352 } | 1351 } |
| 1353 | 1352 |
| 1354 | 1353 |
| 1355 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1354 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1356 Label* slow) { | 1355 Label* slow) { |
| 1357 ASSERT(var->IsContextSlot()); | 1356 ASSERT(var->IsContextSlot()); |
| 1358 Register context = rsi; | 1357 Register context = rsi; |
| 1359 Register temp = rbx; | 1358 Register temp = rbx; |
| 1360 | 1359 |
| 1361 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1360 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 | 1420 |
| 1422 // Three cases: global variables, lookup variables, and all other types of | 1421 // Three cases: global variables, lookup variables, and all other types of |
| 1423 // variables. | 1422 // variables. |
| 1424 switch (var->location()) { | 1423 switch (var->location()) { |
| 1425 case Variable::UNALLOCATED: { | 1424 case Variable::UNALLOCATED: { |
| 1426 Comment cmnt(masm_, "Global variable"); | 1425 Comment cmnt(masm_, "Global variable"); |
| 1427 // Use inline caching. Variable name is passed in rcx and the global | 1426 // Use inline caching. Variable name is passed in rcx and the global |
| 1428 // object on the stack. | 1427 // object on the stack. |
| 1429 __ Move(rcx, var->name()); | 1428 __ Move(rcx, var->name()); |
| 1430 __ movq(rax, GlobalObjectOperand()); | 1429 __ movq(rax, GlobalObjectOperand()); |
| 1431 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1430 CallLoadIC(CONTEXTUAL); |
| 1432 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 1433 context()->Plug(rax); | 1431 context()->Plug(rax); |
| 1434 break; | 1432 break; |
| 1435 } | 1433 } |
| 1436 | 1434 |
| 1437 case Variable::PARAMETER: | 1435 case Variable::PARAMETER: |
| 1438 case Variable::LOCAL: | 1436 case Variable::LOCAL: |
| 1439 case Variable::CONTEXT: { | 1437 case Variable::CONTEXT: { |
| 1440 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); | 1438 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); |
| 1441 if (var->binding_needs_init()) { | 1439 if (var->binding_needs_init()) { |
| 1442 // var->scope() may be NULL when the proxy is located in eval code and | 1440 // var->scope() may be NULL when the proxy is located in eval code and |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1636 UNREACHABLE(); | 1634 UNREACHABLE(); |
| 1637 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1635 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1638 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1636 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1639 // Fall through. | 1637 // Fall through. |
| 1640 case ObjectLiteral::Property::COMPUTED: | 1638 case ObjectLiteral::Property::COMPUTED: |
| 1641 if (key->value()->IsInternalizedString()) { | 1639 if (key->value()->IsInternalizedString()) { |
| 1642 if (property->emit_store()) { | 1640 if (property->emit_store()) { |
| 1643 VisitForAccumulatorValue(value); | 1641 VisitForAccumulatorValue(value); |
| 1644 __ Move(rcx, key->value()); | 1642 __ Move(rcx, key->value()); |
| 1645 __ movq(rdx, Operand(rsp, 0)); | 1643 __ movq(rdx, Operand(rsp, 0)); |
| 1646 Handle<Code> ic = is_classic_mode() | 1644 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
| 1647 ? isolate()->builtins()->StoreIC_Initialize() | |
| 1648 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 1649 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
| 1650 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1645 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1651 } else { | 1646 } else { |
| 1652 VisitForEffect(value); | 1647 VisitForEffect(value); |
| 1653 } | 1648 } |
| 1654 break; | 1649 break; |
| 1655 } | 1650 } |
| 1656 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1651 __ push(Operand(rsp, 0)); // Duplicate receiver. |
| 1657 VisitForStackValue(key); | 1652 VisitForStackValue(key); |
| 1658 VisitForStackValue(value); | 1653 VisitForStackValue(value); |
| 1659 if (property->emit_store()) { | 1654 if (property->emit_store()) { |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2061 __ bind(&l_call); | 2056 __ bind(&l_call); |
| 2062 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2057 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
| 2063 CallIC(ic); | 2058 CallIC(ic); |
| 2064 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2059 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2065 __ Drop(1); // The key is still on the stack; drop it. | 2060 __ Drop(1); // The key is still on the stack; drop it. |
| 2066 | 2061 |
| 2067 // if (!result.done) goto l_try; | 2062 // if (!result.done) goto l_try; |
| 2068 __ bind(&l_loop); | 2063 __ bind(&l_loop); |
| 2069 __ push(rax); // save result | 2064 __ push(rax); // save result |
| 2070 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" | 2065 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" |
| 2071 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2066 CallLoadIC(NOT_CONTEXTUAL); // result.done in rax |
| 2072 CallIC(done_ic); // result.done in rax | |
| 2073 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2067 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2074 CallIC(bool_ic); | 2068 CallIC(bool_ic); |
| 2075 __ testq(result_register(), result_register()); | 2069 __ testq(result_register(), result_register()); |
| 2076 __ j(zero, &l_try); | 2070 __ j(zero, &l_try); |
| 2077 | 2071 |
| 2078 // result.value | 2072 // result.value |
| 2079 __ pop(rax); // result | 2073 __ pop(rax); // result |
| 2080 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" | 2074 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" |
| 2081 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2075 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax |
| 2082 CallIC(value_ic); // result.value in rax | |
| 2083 context()->DropAndPlug(2, rax); // drop iter and g | 2076 context()->DropAndPlug(2, rax); // drop iter and g |
| 2084 break; | 2077 break; |
| 2085 } | 2078 } |
| 2086 } | 2079 } |
| 2087 } | 2080 } |
| 2088 | 2081 |
| 2089 | 2082 |
| 2090 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2083 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2091 Expression *value, | 2084 Expression *value, |
| 2092 JSGeneratorObject::ResumeMode resume_mode) { | 2085 JSGeneratorObject::ResumeMode resume_mode) { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2218 // root set. | 2211 // root set. |
| 2219 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | 2212 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, |
| 2220 rcx, rdx, kDontSaveFPRegs); | 2213 rcx, rdx, kDontSaveFPRegs); |
| 2221 } | 2214 } |
| 2222 | 2215 |
| 2223 | 2216 |
| 2224 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2217 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2225 SetSourcePosition(prop->position()); | 2218 SetSourcePosition(prop->position()); |
| 2226 Literal* key = prop->key()->AsLiteral(); | 2219 Literal* key = prop->key()->AsLiteral(); |
| 2227 __ Move(rcx, key->value()); | 2220 __ Move(rcx, key->value()); |
| 2228 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2221 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2229 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
| 2230 } | 2222 } |
| 2231 | 2223 |
| 2232 | 2224 |
| 2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2225 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2234 SetSourcePosition(prop->position()); | 2226 SetSourcePosition(prop->position()); |
| 2235 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2227 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2236 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2228 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2237 } | 2229 } |
| 2238 | 2230 |
| 2239 | 2231 |
| 2240 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2232 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2241 Token::Value op, | 2233 Token::Value op, |
| 2242 OverwriteMode mode, | 2234 OverwriteMode mode, |
| 2243 Expression* left, | 2235 Expression* left, |
| 2244 Expression* right) { | 2236 Expression* right) { |
| 2245 // Do combined smi check of the operands. Left operand is on the | 2237 // Do combined smi check of the operands. Left operand is on the |
| 2246 // stack (popped into rdx). Right operand is in rax but moved into | 2238 // stack (popped into rdx). Right operand is in rax but moved into |
| 2247 // rcx to make the shifts easier. | 2239 // rcx to make the shifts easier. |
| 2248 Label done, stub_call, smi_case; | 2240 Label done, stub_call, smi_case; |
| 2249 __ pop(rdx); | 2241 __ pop(rdx); |
| 2250 __ movq(rcx, rax); | 2242 __ movq(rcx, rax); |
| 2251 __ or_(rax, rdx); | 2243 __ or_(rax, rdx); |
| 2252 JumpPatchSite patch_site(masm_); | 2244 JumpPatchSite patch_site(masm_); |
| 2253 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 2245 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
| 2254 | 2246 |
| 2255 __ bind(&stub_call); | 2247 __ bind(&stub_call); |
| 2256 __ movq(rax, rcx); | 2248 __ movq(rax, rcx); |
| 2257 BinaryOpICStub stub(op, mode); | 2249 BinaryOpICStub stub(op, mode); |
| 2258 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2250 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2259 expr->BinaryOperationFeedbackId()); | 2251 expr->BinaryOperationFeedbackId()); |
| 2260 patch_site.EmitPatchInfo(); | 2252 patch_site.EmitPatchInfo(); |
| 2261 __ jmp(&done, Label::kNear); | 2253 __ jmp(&done, Label::kNear); |
| 2262 | 2254 |
| 2263 __ bind(&smi_case); | 2255 __ bind(&smi_case); |
| 2264 switch (op) { | 2256 switch (op) { |
| 2265 case Token::SAR: | 2257 case Token::SAR: |
| 2266 __ SmiShiftArithmeticRight(rax, rdx, rcx); | 2258 __ SmiShiftArithmeticRight(rax, rdx, rcx); |
| 2267 break; | 2259 break; |
| 2268 case Token::SHL: | 2260 case Token::SHL: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2298 context()->Plug(rax); | 2290 context()->Plug(rax); |
| 2299 } | 2291 } |
| 2300 | 2292 |
| 2301 | 2293 |
| 2302 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2294 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2303 Token::Value op, | 2295 Token::Value op, |
| 2304 OverwriteMode mode) { | 2296 OverwriteMode mode) { |
| 2305 __ pop(rdx); | 2297 __ pop(rdx); |
| 2306 BinaryOpICStub stub(op, mode); | 2298 BinaryOpICStub stub(op, mode); |
| 2307 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2299 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 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 context()->Plug(rax); | 2303 context()->Plug(rax); |
| 2312 } | 2304 } |
| 2313 | 2305 |
| 2314 | 2306 |
| 2315 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2307 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2316 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2308 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
| 2317 // ReferenceError' on the left-hand side. | 2309 // ReferenceError' on the left-hand side. |
| 2318 if (!expr->IsValidLeftHandSide()) { | 2310 if (!expr->IsValidLeftHandSide()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2337 EffectContext context(this); | 2329 EffectContext context(this); |
| 2338 EmitVariableAssignment(var, Token::ASSIGN); | 2330 EmitVariableAssignment(var, Token::ASSIGN); |
| 2339 break; | 2331 break; |
| 2340 } | 2332 } |
| 2341 case NAMED_PROPERTY: { | 2333 case NAMED_PROPERTY: { |
| 2342 __ push(rax); // Preserve value. | 2334 __ push(rax); // Preserve value. |
| 2343 VisitForAccumulatorValue(prop->obj()); | 2335 VisitForAccumulatorValue(prop->obj()); |
| 2344 __ movq(rdx, rax); | 2336 __ movq(rdx, rax); |
| 2345 __ pop(rax); // Restore value. | 2337 __ pop(rax); // Restore value. |
| 2346 __ Move(rcx, prop->key()->AsLiteral()->value()); | 2338 __ Move(rcx, prop->key()->AsLiteral()->value()); |
| 2347 Handle<Code> ic = is_classic_mode() | 2339 CallStoreIC(NOT_CONTEXTUAL); |
| 2348 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2349 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2350 CallIC(ic); | |
| 2351 break; | 2340 break; |
| 2352 } | 2341 } |
| 2353 case KEYED_PROPERTY: { | 2342 case KEYED_PROPERTY: { |
| 2354 __ push(rax); // Preserve value. | 2343 __ push(rax); // Preserve value. |
| 2355 VisitForStackValue(prop->obj()); | 2344 VisitForStackValue(prop->obj()); |
| 2356 VisitForAccumulatorValue(prop->key()); | 2345 VisitForAccumulatorValue(prop->key()); |
| 2357 __ movq(rcx, rax); | 2346 __ movq(rcx, rax); |
| 2358 __ pop(rdx); | 2347 __ pop(rdx); |
| 2359 __ pop(rax); // Restore value. | 2348 __ pop(rax); // Restore value. |
| 2360 Handle<Code> ic = is_classic_mode() | 2349 Handle<Code> ic = is_classic_mode() |
| 2361 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2350 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2362 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2351 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2363 CallIC(ic); | 2352 CallIC(ic); |
| 2364 break; | 2353 break; |
| 2365 } | 2354 } |
| 2366 } | 2355 } |
| 2367 context()->Plug(rax); | 2356 context()->Plug(rax); |
| 2368 } | 2357 } |
| 2369 | 2358 |
| 2370 | 2359 |
| 2371 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2360 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2372 Token::Value op) { | 2361 Token::Value op) { |
| 2373 if (var->IsUnallocated()) { | 2362 if (var->IsUnallocated()) { |
| 2374 // Global var, const, or let. | 2363 // Global var, const, or let. |
| 2375 __ Move(rcx, var->name()); | 2364 __ Move(rcx, var->name()); |
| 2376 __ movq(rdx, GlobalObjectOperand()); | 2365 __ movq(rdx, GlobalObjectOperand()); |
| 2377 Handle<Code> ic = is_classic_mode() | 2366 CallStoreIC(CONTEXTUAL); |
| 2378 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2379 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2380 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 2381 } else if (op == Token::INIT_CONST) { | 2367 } else if (op == Token::INIT_CONST) { |
| 2382 // Const initializers need a write barrier. | 2368 // Const initializers need a write barrier. |
| 2383 ASSERT(!var->IsParameter()); // No const parameters. | 2369 ASSERT(!var->IsParameter()); // No const parameters. |
| 2384 if (var->IsStackLocal()) { | 2370 if (var->IsStackLocal()) { |
| 2385 Label skip; | 2371 Label skip; |
| 2386 __ movq(rdx, StackOperand(var)); | 2372 __ movq(rdx, StackOperand(var)); |
| 2387 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 2373 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |
| 2388 __ j(not_equal, &skip); | 2374 __ j(not_equal, &skip); |
| 2389 __ movq(StackOperand(var), rax); | 2375 __ movq(StackOperand(var), rax); |
| 2390 __ bind(&skip); | 2376 __ bind(&skip); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2461 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2447 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2462 // Assignment to a property, using a named store IC. | 2448 // Assignment to a property, using a named store IC. |
| 2463 Property* prop = expr->target()->AsProperty(); | 2449 Property* prop = expr->target()->AsProperty(); |
| 2464 ASSERT(prop != NULL); | 2450 ASSERT(prop != NULL); |
| 2465 ASSERT(prop->key()->AsLiteral() != NULL); | 2451 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2466 | 2452 |
| 2467 // Record source code position before IC call. | 2453 // Record source code position before IC call. |
| 2468 SetSourcePosition(expr->position()); | 2454 SetSourcePosition(expr->position()); |
| 2469 __ Move(rcx, prop->key()->AsLiteral()->value()); | 2455 __ Move(rcx, prop->key()->AsLiteral()->value()); |
| 2470 __ pop(rdx); | 2456 __ pop(rdx); |
| 2471 Handle<Code> ic = is_classic_mode() | 2457 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2472 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2473 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2474 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
| 2475 | 2458 |
| 2476 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2459 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2477 context()->Plug(rax); | 2460 context()->Plug(rax); |
| 2478 } | 2461 } |
| 2479 | 2462 |
| 2480 | 2463 |
| 2481 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2464 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2482 // Assignment to a property, using a keyed store IC. | 2465 // Assignment to a property, using a keyed store IC. |
| 2483 | 2466 |
| 2484 __ pop(rcx); | 2467 __ pop(rcx); |
| 2485 __ pop(rdx); | 2468 __ pop(rdx); |
| 2486 // Record source code position before IC call. | 2469 // Record source code position before IC call. |
| 2487 SetSourcePosition(expr->position()); | 2470 SetSourcePosition(expr->position()); |
| 2488 Handle<Code> ic = is_classic_mode() | 2471 Handle<Code> ic = is_classic_mode() |
| 2489 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2472 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2490 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2473 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2491 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2474 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2492 | 2475 |
| 2493 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2476 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2494 context()->Plug(rax); | 2477 context()->Plug(rax); |
| 2495 } | 2478 } |
| 2496 | 2479 |
| 2497 | 2480 |
| 2498 void FullCodeGenerator::VisitProperty(Property* expr) { | 2481 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2499 Comment cmnt(masm_, "[ Property"); | 2482 Comment cmnt(masm_, "[ Property"); |
| 2500 Expression* key = expr->key(); | 2483 Expression* key = expr->key(); |
| 2501 | 2484 |
| 2502 if (key->IsPropertyName()) { | 2485 if (key->IsPropertyName()) { |
| 2503 VisitForAccumulatorValue(expr->obj()); | 2486 VisitForAccumulatorValue(expr->obj()); |
| 2504 EmitNamedPropertyLoad(expr); | 2487 EmitNamedPropertyLoad(expr); |
| 2505 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2488 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2506 context()->Plug(rax); | 2489 context()->Plug(rax); |
| 2507 } else { | 2490 } else { |
| 2508 VisitForStackValue(expr->obj()); | 2491 VisitForStackValue(expr->obj()); |
| 2509 VisitForAccumulatorValue(expr->key()); | 2492 VisitForAccumulatorValue(expr->key()); |
| 2510 __ pop(rdx); | 2493 __ pop(rdx); |
| 2511 EmitKeyedPropertyLoad(expr); | 2494 EmitKeyedPropertyLoad(expr); |
| 2512 context()->Plug(rax); | 2495 context()->Plug(rax); |
| 2513 } | 2496 } |
| 2514 } | 2497 } |
| 2515 | 2498 |
| 2516 | 2499 |
| 2517 void FullCodeGenerator::CallIC(Handle<Code> code, | 2500 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2518 RelocInfo::Mode rmode, | 2501 ContextualMode mode, |
| 2519 TypeFeedbackId ast_id) { | 2502 TypeFeedbackId ast_id) { |
| 2520 ic_total_count_++; | 2503 ic_total_count_++; |
| 2521 __ call(code, rmode, ast_id); | 2504 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
| 2505 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
| 2522 } | 2506 } |
| 2523 | 2507 |
| 2524 | 2508 |
| 2525 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2509 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 2526 Handle<Object> name, | 2510 Handle<Object> name, |
| 2527 RelocInfo::Mode mode) { | 2511 ContextualMode mode) { |
| 2528 // Code common for calls using the IC. | 2512 // Code common for calls using the IC. |
| 2529 ZoneList<Expression*>* args = expr->arguments(); | 2513 ZoneList<Expression*>* args = expr->arguments(); |
| 2530 int arg_count = args->length(); | 2514 int arg_count = args->length(); |
| 2531 { PreservePositionScope scope(masm()->positions_recorder()); | 2515 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2532 for (int i = 0; i < arg_count; i++) { | 2516 for (int i = 0; i < arg_count; i++) { |
| 2533 VisitForStackValue(args->at(i)); | 2517 VisitForStackValue(args->at(i)); |
| 2534 } | 2518 } |
| 2535 __ Move(rcx, name); | 2519 __ Move(rcx, name); |
| 2536 } | 2520 } |
| 2537 // Record source position for debugger. | 2521 // Record source position for debugger. |
| 2538 SetSourcePosition(expr->position()); | 2522 SetSourcePosition(expr->position()); |
| 2539 // Call the IC initialization code. | 2523 // Call the IC initialization code. |
| 2540 Handle<Code> ic = | 2524 Handle<Code> ic = |
| 2541 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2525 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2542 CallIC(ic, mode, expr->CallFeedbackId()); | 2526 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2527 ? TypeFeedbackId::None() |
| 2528 : expr->CallFeedbackId(); |
| 2529 CallIC(ic, mode, ast_id); |
| 2543 RecordJSReturnSite(expr); | 2530 RecordJSReturnSite(expr); |
| 2544 // Restore context register. | 2531 // Restore context register. |
| 2545 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2532 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2546 context()->Plug(rax); | 2533 context()->Plug(rax); |
| 2547 } | 2534 } |
| 2548 | 2535 |
| 2549 | 2536 |
| 2550 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2537 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2551 Expression* key) { | 2538 Expression* key) { |
| 2552 // Load the key. | 2539 // Load the key. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2565 for (int i = 0; i < arg_count; i++) { | 2552 for (int i = 0; i < arg_count; i++) { |
| 2566 VisitForStackValue(args->at(i)); | 2553 VisitForStackValue(args->at(i)); |
| 2567 } | 2554 } |
| 2568 } | 2555 } |
| 2569 // Record source position for debugger. | 2556 // Record source position for debugger. |
| 2570 SetSourcePosition(expr->position()); | 2557 SetSourcePosition(expr->position()); |
| 2571 // Call the IC initialization code. | 2558 // Call the IC initialization code. |
| 2572 Handle<Code> ic = | 2559 Handle<Code> ic = |
| 2573 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2560 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2574 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 2561 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
| 2575 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2562 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
| 2576 RecordJSReturnSite(expr); | 2563 RecordJSReturnSite(expr); |
| 2577 // Restore context register. | 2564 // Restore context register. |
| 2578 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2565 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2579 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 2566 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
| 2580 } | 2567 } |
| 2581 | 2568 |
| 2582 | 2569 |
| 2583 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2570 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2584 // Code common for calls using the call stub. | 2571 // Code common for calls using the call stub. |
| 2585 ZoneList<Expression*>* args = expr->arguments(); | 2572 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2677 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2664 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
| 2678 __ CallStub(&stub); | 2665 __ CallStub(&stub); |
| 2679 RecordJSReturnSite(expr); | 2666 RecordJSReturnSite(expr); |
| 2680 // Restore context register. | 2667 // Restore context register. |
| 2681 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2668 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2682 context()->DropAndPlug(1, rax); | 2669 context()->DropAndPlug(1, rax); |
| 2683 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2670 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 2684 // Call to a global variable. Push global object as receiver for the | 2671 // Call to a global variable. Push global object as receiver for the |
| 2685 // call IC lookup. | 2672 // call IC lookup. |
| 2686 __ push(GlobalObjectOperand()); | 2673 __ push(GlobalObjectOperand()); |
| 2687 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2674 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
| 2688 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2675 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 2689 // Call to a lookup slot (dynamically introduced variable). | 2676 // Call to a lookup slot (dynamically introduced variable). |
| 2690 Label slow, done; | 2677 Label slow, done; |
| 2691 | 2678 |
| 2692 { PreservePositionScope scope(masm()->positions_recorder()); | 2679 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2693 // Generate code for loading from variables potentially shadowed by | 2680 // Generate code for loading from variables potentially shadowed by |
| 2694 // eval-introduced variables. | 2681 // eval-introduced variables. |
| 2695 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2682 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2696 } | 2683 } |
| 2697 __ bind(&slow); | 2684 __ bind(&slow); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2721 // LoadContextSlot. That object could be the hole if the receiver is | 2708 // LoadContextSlot. That object could be the hole if the receiver is |
| 2722 // implicitly the global object. | 2709 // implicitly the global object. |
| 2723 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2710 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2724 } else if (property != NULL) { | 2711 } else if (property != NULL) { |
| 2725 { PreservePositionScope scope(masm()->positions_recorder()); | 2712 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2726 VisitForStackValue(property->obj()); | 2713 VisitForStackValue(property->obj()); |
| 2727 } | 2714 } |
| 2728 if (property->key()->IsPropertyName()) { | 2715 if (property->key()->IsPropertyName()) { |
| 2729 EmitCallWithIC(expr, | 2716 EmitCallWithIC(expr, |
| 2730 property->key()->AsLiteral()->value(), | 2717 property->key()->AsLiteral()->value(), |
| 2731 RelocInfo::CODE_TARGET); | 2718 NOT_CONTEXTUAL); |
| 2732 } else { | 2719 } else { |
| 2733 EmitKeyedCallWithIC(expr, property->key()); | 2720 EmitKeyedCallWithIC(expr, property->key()); |
| 2734 } | 2721 } |
| 2735 } else { | 2722 } else { |
| 2736 // Call to an arbitrary expression not handled specially above. | 2723 // Call to an arbitrary expression not handled specially above. |
| 2737 { PreservePositionScope scope(masm()->positions_recorder()); | 2724 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2738 VisitForStackValue(callee); | 2725 VisitForStackValue(callee); |
| 2739 } | 2726 } |
| 2740 // Load global receiver object. | 2727 // Load global receiver object. |
| 2741 __ movq(rbx, GlobalObjectOperand()); | 2728 __ movq(rbx, GlobalObjectOperand()); |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4132 | 4119 |
| 4133 // Push the arguments ("left-to-right"). | 4120 // Push the arguments ("left-to-right"). |
| 4134 int arg_count = args->length(); | 4121 int arg_count = args->length(); |
| 4135 for (int i = 0; i < arg_count; i++) { | 4122 for (int i = 0; i < arg_count; i++) { |
| 4136 VisitForStackValue(args->at(i)); | 4123 VisitForStackValue(args->at(i)); |
| 4137 } | 4124 } |
| 4138 | 4125 |
| 4139 if (expr->is_jsruntime()) { | 4126 if (expr->is_jsruntime()) { |
| 4140 // Call the JS runtime function using a call IC. | 4127 // Call the JS runtime function using a call IC. |
| 4141 __ Move(rcx, expr->name()); | 4128 __ Move(rcx, expr->name()); |
| 4142 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4129 ContextualMode mode = NOT_CONTEXTUAL; |
| 4143 Handle<Code> ic = | 4130 Handle<Code> ic = |
| 4144 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4131 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 4145 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4132 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
| 4146 // Restore context register. | 4133 // Restore context register. |
| 4147 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4134 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 4148 } else { | 4135 } else { |
| 4149 __ CallRuntime(expr->function(), arg_count); | 4136 __ CallRuntime(expr->function(), arg_count); |
| 4150 } | 4137 } |
| 4151 context()->Plug(rax); | 4138 context()->Plug(rax); |
| 4152 } | 4139 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4386 | 4373 |
| 4387 // Record position before stub call. | 4374 // Record position before stub call. |
| 4388 SetSourcePosition(expr->position()); | 4375 SetSourcePosition(expr->position()); |
| 4389 | 4376 |
| 4390 // Call stub for +1/-1. | 4377 // Call stub for +1/-1. |
| 4391 __ bind(&stub_call); | 4378 __ bind(&stub_call); |
| 4392 __ movq(rdx, rax); | 4379 __ movq(rdx, rax); |
| 4393 __ Move(rax, Smi::FromInt(1)); | 4380 __ Move(rax, Smi::FromInt(1)); |
| 4394 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); | 4381 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); |
| 4395 CallIC(stub.GetCode(isolate()), | 4382 CallIC(stub.GetCode(isolate()), |
| 4396 RelocInfo::CODE_TARGET, | 4383 NOT_CONTEXTUAL, |
| 4397 expr->CountBinOpFeedbackId()); | 4384 expr->CountBinOpFeedbackId()); |
| 4398 patch_site.EmitPatchInfo(); | 4385 patch_site.EmitPatchInfo(); |
| 4399 __ bind(&done); | 4386 __ bind(&done); |
| 4400 | 4387 |
| 4401 // Store the value returned in rax. | 4388 // Store the value returned in rax. |
| 4402 switch (assign_type) { | 4389 switch (assign_type) { |
| 4403 case VARIABLE: | 4390 case VARIABLE: |
| 4404 if (expr->is_postfix()) { | 4391 if (expr->is_postfix()) { |
| 4405 // Perform the assignment as if via '='. | 4392 // Perform the assignment as if via '='. |
| 4406 { EffectContext context(this); | 4393 { EffectContext context(this); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4418 // Perform the assignment as if via '='. | 4405 // Perform the assignment as if via '='. |
| 4419 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4406 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4420 Token::ASSIGN); | 4407 Token::ASSIGN); |
| 4421 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4408 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4422 context()->Plug(rax); | 4409 context()->Plug(rax); |
| 4423 } | 4410 } |
| 4424 break; | 4411 break; |
| 4425 case NAMED_PROPERTY: { | 4412 case NAMED_PROPERTY: { |
| 4426 __ Move(rcx, prop->key()->AsLiteral()->value()); | 4413 __ Move(rcx, prop->key()->AsLiteral()->value()); |
| 4427 __ pop(rdx); | 4414 __ pop(rdx); |
| 4428 Handle<Code> ic = is_classic_mode() | 4415 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4429 ? isolate()->builtins()->StoreIC_Initialize() | |
| 4430 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 4431 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
| 4432 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4416 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4433 if (expr->is_postfix()) { | 4417 if (expr->is_postfix()) { |
| 4434 if (!context()->IsEffect()) { | 4418 if (!context()->IsEffect()) { |
| 4435 context()->PlugTOS(); | 4419 context()->PlugTOS(); |
| 4436 } | 4420 } |
| 4437 } else { | 4421 } else { |
| 4438 context()->Plug(rax); | 4422 context()->Plug(rax); |
| 4439 } | 4423 } |
| 4440 break; | 4424 break; |
| 4441 } | 4425 } |
| 4442 case KEYED_PROPERTY: { | 4426 case KEYED_PROPERTY: { |
| 4443 __ pop(rcx); | 4427 __ pop(rcx); |
| 4444 __ pop(rdx); | 4428 __ pop(rdx); |
| 4445 Handle<Code> ic = is_classic_mode() | 4429 Handle<Code> ic = is_classic_mode() |
| 4446 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4430 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4447 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4431 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4448 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4432 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4449 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4433 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4450 if (expr->is_postfix()) { | 4434 if (expr->is_postfix()) { |
| 4451 if (!context()->IsEffect()) { | 4435 if (!context()->IsEffect()) { |
| 4452 context()->PlugTOS(); | 4436 context()->PlugTOS(); |
| 4453 } | 4437 } |
| 4454 } else { | 4438 } else { |
| 4455 context()->Plug(rax); | 4439 context()->Plug(rax); |
| 4456 } | 4440 } |
| 4457 break; | 4441 break; |
| 4458 } | 4442 } |
| 4459 } | 4443 } |
| 4460 } | 4444 } |
| 4461 | 4445 |
| 4462 | 4446 |
| 4463 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4447 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4464 VariableProxy* proxy = expr->AsVariableProxy(); | 4448 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4465 ASSERT(!context()->IsEffect()); | 4449 ASSERT(!context()->IsEffect()); |
| 4466 ASSERT(!context()->IsTest()); | 4450 ASSERT(!context()->IsTest()); |
| 4467 | 4451 |
| 4468 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4452 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4469 Comment cmnt(masm_, "Global variable"); | 4453 Comment cmnt(masm_, "Global variable"); |
| 4470 __ Move(rcx, proxy->name()); | 4454 __ Move(rcx, proxy->name()); |
| 4471 __ movq(rax, GlobalObjectOperand()); | 4455 __ movq(rax, GlobalObjectOperand()); |
| 4472 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
| 4473 // Use a regular load, not a contextual load, to avoid a reference | 4456 // Use a regular load, not a contextual load, to avoid a reference |
| 4474 // error. | 4457 // error. |
| 4475 CallIC(ic); | 4458 CallLoadIC(NOT_CONTEXTUAL); |
| 4476 PrepareForBailout(expr, TOS_REG); | 4459 PrepareForBailout(expr, TOS_REG); |
| 4477 context()->Plug(rax); | 4460 context()->Plug(rax); |
| 4478 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4461 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4479 Label done, slow; | 4462 Label done, slow; |
| 4480 | 4463 |
| 4481 // Generate code for loading from variables potentially shadowed | 4464 // Generate code for loading from variables potentially shadowed |
| 4482 // by eval-introduced variables. | 4465 // by eval-introduced variables. |
| 4483 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4466 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4484 | 4467 |
| 4485 __ bind(&slow); | 4468 __ bind(&slow); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4627 __ or_(rcx, rax); | 4610 __ or_(rcx, rax); |
| 4628 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); | 4611 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); |
| 4629 __ cmpq(rdx, rax); | 4612 __ cmpq(rdx, rax); |
| 4630 Split(cc, if_true, if_false, NULL); | 4613 Split(cc, if_true, if_false, NULL); |
| 4631 __ bind(&slow_case); | 4614 __ bind(&slow_case); |
| 4632 } | 4615 } |
| 4633 | 4616 |
| 4634 // Record position and call the compare IC. | 4617 // Record position and call the compare IC. |
| 4635 SetSourcePosition(expr->position()); | 4618 SetSourcePosition(expr->position()); |
| 4636 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4619 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 4637 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4620 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4638 patch_site.EmitPatchInfo(); | 4621 patch_site.EmitPatchInfo(); |
| 4639 | 4622 |
| 4640 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4623 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4641 __ testq(rax, rax); | 4624 __ testq(rax, rax); |
| 4642 Split(cc, if_true, if_false, fall_through); | 4625 Split(cc, if_true, if_false, fall_through); |
| 4643 } | 4626 } |
| 4644 } | 4627 } |
| 4645 | 4628 |
| 4646 // Convert the result of the comparison into one expected for this | 4629 // Convert the result of the comparison into one expected for this |
| 4647 // expression's context. | 4630 // expression's context. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4662 VisitForAccumulatorValue(sub_expr); | 4645 VisitForAccumulatorValue(sub_expr); |
| 4663 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4646 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4664 if (expr->op() == Token::EQ_STRICT) { | 4647 if (expr->op() == Token::EQ_STRICT) { |
| 4665 Heap::RootListIndex nil_value = nil == kNullValue ? | 4648 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4666 Heap::kNullValueRootIndex : | 4649 Heap::kNullValueRootIndex : |
| 4667 Heap::kUndefinedValueRootIndex; | 4650 Heap::kUndefinedValueRootIndex; |
| 4668 __ CompareRoot(rax, nil_value); | 4651 __ CompareRoot(rax, nil_value); |
| 4669 Split(equal, if_true, if_false, fall_through); | 4652 Split(equal, if_true, if_false, fall_through); |
| 4670 } else { | 4653 } else { |
| 4671 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4654 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
| 4672 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4655 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4673 __ testq(rax, rax); | 4656 __ testq(rax, rax); |
| 4674 Split(not_zero, if_true, if_false, fall_through); | 4657 Split(not_zero, if_true, if_false, fall_through); |
| 4675 } | 4658 } |
| 4676 context()->Plug(if_true, if_false); | 4659 context()->Plug(if_true, if_false); |
| 4677 } | 4660 } |
| 4678 | 4661 |
| 4679 | 4662 |
| 4680 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4663 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 4681 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 4664 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4682 context()->Plug(rax); | 4665 context()->Plug(rax); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4894 | 4877 |
| 4895 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4878 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4896 Assembler::target_address_at(call_target_address)); | 4879 Assembler::target_address_at(call_target_address)); |
| 4897 return OSR_AFTER_STACK_CHECK; | 4880 return OSR_AFTER_STACK_CHECK; |
| 4898 } | 4881 } |
| 4899 | 4882 |
| 4900 | 4883 |
| 4901 } } // namespace v8::internal | 4884 } } // namespace v8::internal |
| 4902 | 4885 |
| 4903 #endif // V8_TARGET_ARCH_X64 | 4886 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |