OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 ASSERT(materialize_true == materialize_false); | 474 ASSERT(materialize_true == materialize_false); |
475 __ bind(materialize_true); | 475 __ bind(materialize_true); |
476 } | 476 } |
477 | 477 |
478 | 478 |
479 void FullCodeGenerator::AccumulatorValueContext::Plug( | 479 void FullCodeGenerator::AccumulatorValueContext::Plug( |
480 Label* materialize_true, | 480 Label* materialize_true, |
481 Label* materialize_false) const { | 481 Label* materialize_false) const { |
482 NearLabel done; | 482 NearLabel done; |
483 __ bind(materialize_true); | 483 __ bind(materialize_true); |
484 __ Move(result_register(), Factory::true_value()); | 484 __ Move(result_register(), isolate()->factory()->true_value()); |
485 __ jmp(&done); | 485 __ jmp(&done); |
486 __ bind(materialize_false); | 486 __ bind(materialize_false); |
487 __ Move(result_register(), Factory::false_value()); | 487 __ Move(result_register(), isolate()->factory()->false_value()); |
488 __ bind(&done); | 488 __ bind(&done); |
489 } | 489 } |
490 | 490 |
491 | 491 |
492 void FullCodeGenerator::StackValueContext::Plug( | 492 void FullCodeGenerator::StackValueContext::Plug( |
493 Label* materialize_true, | 493 Label* materialize_true, |
494 Label* materialize_false) const { | 494 Label* materialize_false) const { |
495 NearLabel done; | 495 NearLabel done; |
496 __ bind(materialize_true); | 496 __ bind(materialize_true); |
497 __ Push(Factory::true_value()); | 497 __ Push(isolate()->factory()->true_value()); |
498 __ jmp(&done); | 498 __ jmp(&done); |
499 __ bind(materialize_false); | 499 __ bind(materialize_false); |
500 __ Push(Factory::false_value()); | 500 __ Push(isolate()->factory()->false_value()); |
501 __ bind(&done); | 501 __ bind(&done); |
502 } | 502 } |
503 | 503 |
504 | 504 |
505 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 505 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
506 Label* materialize_false) const { | 506 Label* materialize_false) const { |
507 ASSERT(materialize_true == true_label_); | 507 ASSERT(materialize_true == true_label_); |
508 ASSERT(materialize_false == false_label_); | 508 ASSERT(materialize_false == false_label_); |
509 } | 509 } |
510 | 510 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 VisitForAccumulatorValue(function); | 733 VisitForAccumulatorValue(function); |
734 __ pop(rdx); | 734 __ pop(rdx); |
735 } else { | 735 } else { |
736 __ movq(rdx, rax); | 736 __ movq(rdx, rax); |
737 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); | 737 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); |
738 } | 738 } |
739 ASSERT(prop->key()->AsLiteral() != NULL && | 739 ASSERT(prop->key()->AsLiteral() != NULL && |
740 prop->key()->AsLiteral()->handle()->IsSmi()); | 740 prop->key()->AsLiteral()->handle()->IsSmi()); |
741 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 741 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
742 | 742 |
743 Handle<Code> ic(Builtins::builtin( | 743 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
744 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 744 ? Builtins::KeyedStoreIC_Initialize_Strict |
745 : Builtins::KeyedStoreIC_Initialize)); | 745 : Builtins::KeyedStoreIC_Initialize)); |
746 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 746 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
747 } | 747 } |
748 } | 748 } |
749 } | 749 } |
750 | 750 |
751 | 751 |
752 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 752 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
753 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 753 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
754 } | 754 } |
755 | 755 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 !FLAG_prepare_always_opt && | 1043 !FLAG_prepare_always_opt && |
1044 !pretenure && | 1044 !pretenure && |
1045 scope()->is_function_scope() && | 1045 scope()->is_function_scope() && |
1046 info->num_literals() == 0) { | 1046 info->num_literals() == 0) { |
1047 FastNewClosureStub stub(info->strict_mode() ? kStrictMode : kNonStrictMode); | 1047 FastNewClosureStub stub(info->strict_mode() ? kStrictMode : kNonStrictMode); |
1048 __ Push(info); | 1048 __ Push(info); |
1049 __ CallStub(&stub); | 1049 __ CallStub(&stub); |
1050 } else { | 1050 } else { |
1051 __ push(rsi); | 1051 __ push(rsi); |
1052 __ Push(info); | 1052 __ Push(info); |
1053 __ Push(pretenure ? Factory::true_value() : Factory::false_value()); | 1053 __ Push(pretenure |
| 1054 ? isolate()->factory()->true_value() |
| 1055 : isolate()->factory()->false_value()); |
1054 __ CallRuntime(Runtime::kNewClosure, 3); | 1056 __ CallRuntime(Runtime::kNewClosure, 3); |
1055 } | 1057 } |
1056 context()->Plug(rax); | 1058 context()->Plug(rax); |
1057 } | 1059 } |
1058 | 1060 |
1059 | 1061 |
1060 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1062 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1061 Comment cmnt(masm_, "[ VariableProxy"); | 1063 Comment cmnt(masm_, "[ VariableProxy"); |
1062 EmitVariableLoad(expr->var()); | 1064 EmitVariableLoad(expr->var()); |
1063 } | 1065 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); | 1114 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); |
1113 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); | 1115 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); |
1114 __ jmp(&next); | 1116 __ jmp(&next); |
1115 __ bind(&fast); | 1117 __ bind(&fast); |
1116 } | 1118 } |
1117 | 1119 |
1118 // All extension objects were empty and it is safe to use a global | 1120 // All extension objects were empty and it is safe to use a global |
1119 // load IC call. | 1121 // load IC call. |
1120 __ movq(rax, GlobalObjectOperand()); | 1122 __ movq(rax, GlobalObjectOperand()); |
1121 __ Move(rcx, slot->var()->name()); | 1123 __ Move(rcx, slot->var()->name()); |
1122 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1124 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1125 Builtins::LoadIC_Initialize)); |
1123 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1126 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
1124 ? RelocInfo::CODE_TARGET | 1127 ? RelocInfo::CODE_TARGET |
1125 : RelocInfo::CODE_TARGET_CONTEXT; | 1128 : RelocInfo::CODE_TARGET_CONTEXT; |
1126 EmitCallIC(ic, mode); | 1129 EmitCallIC(ic, mode); |
1127 } | 1130 } |
1128 | 1131 |
1129 | 1132 |
1130 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1133 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
1131 Slot* slot, | 1134 Slot* slot, |
1132 Label* slow) { | 1135 Label* slow) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 key_literal != NULL && | 1198 key_literal != NULL && |
1196 obj_proxy->IsArguments() && | 1199 obj_proxy->IsArguments() && |
1197 key_literal->handle()->IsSmi()) { | 1200 key_literal->handle()->IsSmi()) { |
1198 // Load arguments object if there are no eval-introduced | 1201 // Load arguments object if there are no eval-introduced |
1199 // variables. Then load the argument from the arguments | 1202 // variables. Then load the argument from the arguments |
1200 // object using keyed load. | 1203 // object using keyed load. |
1201 __ movq(rdx, | 1204 __ movq(rdx, |
1202 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1205 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
1203 slow)); | 1206 slow)); |
1204 __ Move(rax, key_literal->handle()); | 1207 __ Move(rax, key_literal->handle()); |
1205 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1208 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1209 Builtins::KeyedLoadIC_Initialize)); |
1206 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1210 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1207 __ jmp(done); | 1211 __ jmp(done); |
1208 } | 1212 } |
1209 } | 1213 } |
1210 } | 1214 } |
1211 } | 1215 } |
1212 } | 1216 } |
1213 | 1217 |
1214 | 1218 |
1215 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1219 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1216 // Four cases: non-this global variables, lookup slots, all other | 1220 // Four cases: non-this global variables, lookup slots, all other |
1217 // types of slots, and parameters that rewrite to explicit property | 1221 // types of slots, and parameters that rewrite to explicit property |
1218 // accesses on the arguments object. | 1222 // accesses on the arguments object. |
1219 Slot* slot = var->AsSlot(); | 1223 Slot* slot = var->AsSlot(); |
1220 Property* property = var->AsProperty(); | 1224 Property* property = var->AsProperty(); |
1221 | 1225 |
1222 if (var->is_global() && !var->is_this()) { | 1226 if (var->is_global() && !var->is_this()) { |
1223 Comment cmnt(masm_, "Global variable"); | 1227 Comment cmnt(masm_, "Global variable"); |
1224 // Use inline caching. Variable name is passed in rcx and the global | 1228 // Use inline caching. Variable name is passed in rcx and the global |
1225 // object on the stack. | 1229 // object on the stack. |
1226 __ Move(rcx, var->name()); | 1230 __ Move(rcx, var->name()); |
1227 __ movq(rax, GlobalObjectOperand()); | 1231 __ movq(rax, GlobalObjectOperand()); |
1228 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1232 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1233 Builtins::LoadIC_Initialize)); |
1229 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1234 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1230 context()->Plug(rax); | 1235 context()->Plug(rax); |
1231 | 1236 |
1232 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1237 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1233 Label done, slow; | 1238 Label done, slow; |
1234 | 1239 |
1235 // Generate code for loading from variables potentially shadowed | 1240 // Generate code for loading from variables potentially shadowed |
1236 // by eval-introduced variables. | 1241 // by eval-introduced variables. |
1237 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1242 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
1238 | 1243 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 | 1286 |
1282 // Assert that the key is a smi. | 1287 // Assert that the key is a smi. |
1283 Literal* key_literal = property->key()->AsLiteral(); | 1288 Literal* key_literal = property->key()->AsLiteral(); |
1284 ASSERT_NOT_NULL(key_literal); | 1289 ASSERT_NOT_NULL(key_literal); |
1285 ASSERT(key_literal->handle()->IsSmi()); | 1290 ASSERT(key_literal->handle()->IsSmi()); |
1286 | 1291 |
1287 // Load the key. | 1292 // Load the key. |
1288 __ Move(rax, key_literal->handle()); | 1293 __ Move(rax, key_literal->handle()); |
1289 | 1294 |
1290 // Do a keyed property load. | 1295 // Do a keyed property load. |
1291 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1296 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1297 Builtins::KeyedLoadIC_Initialize)); |
1292 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1298 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1293 context()->Plug(rax); | 1299 context()->Plug(rax); |
1294 } | 1300 } |
1295 } | 1301 } |
1296 | 1302 |
1297 | 1303 |
1298 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1304 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1299 Comment cmnt(masm_, "[ RegExpLiteral"); | 1305 Comment cmnt(masm_, "[ RegExpLiteral"); |
1300 Label materialized; | 1306 Label materialized; |
1301 // Registers will be used as follows: | 1307 // Registers will be used as follows: |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 UNREACHABLE(); | 1392 UNREACHABLE(); |
1387 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1393 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1388 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1394 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
1389 // Fall through. | 1395 // Fall through. |
1390 case ObjectLiteral::Property::COMPUTED: | 1396 case ObjectLiteral::Property::COMPUTED: |
1391 if (key->handle()->IsSymbol()) { | 1397 if (key->handle()->IsSymbol()) { |
1392 VisitForAccumulatorValue(value); | 1398 VisitForAccumulatorValue(value); |
1393 __ Move(rcx, key->handle()); | 1399 __ Move(rcx, key->handle()); |
1394 __ movq(rdx, Operand(rsp, 0)); | 1400 __ movq(rdx, Operand(rsp, 0)); |
1395 if (property->emit_store()) { | 1401 if (property->emit_store()) { |
1396 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1402 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1403 Builtins::StoreIC_Initialize)); |
1397 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1404 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1398 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1405 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1399 } | 1406 } |
1400 break; | 1407 break; |
1401 } | 1408 } |
1402 // Fall through. | 1409 // Fall through. |
1403 case ObjectLiteral::Property::PROTOTYPE: | 1410 case ObjectLiteral::Property::PROTOTYPE: |
1404 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1411 __ push(Operand(rsp, 0)); // Duplicate receiver. |
1405 VisitForStackValue(key); | 1412 VisitForStackValue(key); |
1406 VisitForStackValue(value); | 1413 VisitForStackValue(value); |
(...skipping 28 matching lines...) Expand all Loading... |
1435 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1442 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1436 Comment cmnt(masm_, "[ ArrayLiteral"); | 1443 Comment cmnt(masm_, "[ ArrayLiteral"); |
1437 | 1444 |
1438 ZoneList<Expression*>* subexprs = expr->values(); | 1445 ZoneList<Expression*>* subexprs = expr->values(); |
1439 int length = subexprs->length(); | 1446 int length = subexprs->length(); |
1440 | 1447 |
1441 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1448 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1442 __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); | 1449 __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); |
1443 __ Push(Smi::FromInt(expr->literal_index())); | 1450 __ Push(Smi::FromInt(expr->literal_index())); |
1444 __ Push(expr->constant_elements()); | 1451 __ Push(expr->constant_elements()); |
1445 if (expr->constant_elements()->map() == Heap::fixed_cow_array_map()) { | 1452 if (expr->constant_elements()->map() == |
| 1453 isolate()->heap()->fixed_cow_array_map()) { |
1446 FastCloneShallowArrayStub stub( | 1454 FastCloneShallowArrayStub stub( |
1447 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); | 1455 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); |
1448 __ CallStub(&stub); | 1456 __ CallStub(&stub); |
1449 __ IncrementCounter(&Counters::cow_arrays_created_stub, 1); | 1457 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); |
1450 } else if (expr->depth() > 1) { | 1458 } else if (expr->depth() > 1) { |
1451 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1459 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
1452 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1460 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
1453 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 1461 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
1454 } else { | 1462 } else { |
1455 FastCloneShallowArrayStub stub( | 1463 FastCloneShallowArrayStub stub( |
1456 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); | 1464 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); |
1457 __ CallStub(&stub); | 1465 __ CallStub(&stub); |
1458 } | 1466 } |
1459 | 1467 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1623 EmitKeyedPropertyAssignment(expr); | 1631 EmitKeyedPropertyAssignment(expr); |
1624 break; | 1632 break; |
1625 } | 1633 } |
1626 } | 1634 } |
1627 | 1635 |
1628 | 1636 |
1629 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1637 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1630 SetSourcePosition(prop->position()); | 1638 SetSourcePosition(prop->position()); |
1631 Literal* key = prop->key()->AsLiteral(); | 1639 Literal* key = prop->key()->AsLiteral(); |
1632 __ Move(rcx, key->handle()); | 1640 __ Move(rcx, key->handle()); |
1633 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1641 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1642 Builtins::LoadIC_Initialize)); |
1634 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1643 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1635 } | 1644 } |
1636 | 1645 |
1637 | 1646 |
1638 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1647 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1639 SetSourcePosition(prop->position()); | 1648 SetSourcePosition(prop->position()); |
1640 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1649 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1650 Builtins::KeyedLoadIC_Initialize)); |
1641 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1651 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1642 } | 1652 } |
1643 | 1653 |
1644 | 1654 |
1645 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1655 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
1646 Token::Value op, | 1656 Token::Value op, |
1647 OverwriteMode mode, | 1657 OverwriteMode mode, |
1648 Expression* left, | 1658 Expression* left, |
1649 Expression* right) { | 1659 Expression* right) { |
1650 // Do combined smi check of the operands. Left operand is on the | 1660 // Do combined smi check of the operands. Left operand is on the |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 EffectContext context(this); | 1746 EffectContext context(this); |
1737 EmitVariableAssignment(var, Token::ASSIGN); | 1747 EmitVariableAssignment(var, Token::ASSIGN); |
1738 break; | 1748 break; |
1739 } | 1749 } |
1740 case NAMED_PROPERTY: { | 1750 case NAMED_PROPERTY: { |
1741 __ push(rax); // Preserve value. | 1751 __ push(rax); // Preserve value. |
1742 VisitForAccumulatorValue(prop->obj()); | 1752 VisitForAccumulatorValue(prop->obj()); |
1743 __ movq(rdx, rax); | 1753 __ movq(rdx, rax); |
1744 __ pop(rax); // Restore value. | 1754 __ pop(rax); // Restore value. |
1745 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1755 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1746 Handle<Code> ic(Builtins::builtin( | 1756 Handle<Code> ic(isolate()->builtins()->builtin( |
1747 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1757 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1748 : Builtins::StoreIC_Initialize)); | 1758 : Builtins::StoreIC_Initialize)); |
1749 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1759 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1750 break; | 1760 break; |
1751 } | 1761 } |
1752 case KEYED_PROPERTY: { | 1762 case KEYED_PROPERTY: { |
1753 __ push(rax); // Preserve value. | 1763 __ push(rax); // Preserve value. |
1754 if (prop->is_synthetic()) { | 1764 if (prop->is_synthetic()) { |
1755 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1765 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
1756 ASSERT(prop->key()->AsLiteral() != NULL); | 1766 ASSERT(prop->key()->AsLiteral() != NULL); |
1757 { AccumulatorValueContext for_object(this); | 1767 { AccumulatorValueContext for_object(this); |
1758 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1768 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
1759 } | 1769 } |
1760 __ movq(rdx, rax); | 1770 __ movq(rdx, rax); |
1761 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1771 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1762 } else { | 1772 } else { |
1763 VisitForStackValue(prop->obj()); | 1773 VisitForStackValue(prop->obj()); |
1764 VisitForAccumulatorValue(prop->key()); | 1774 VisitForAccumulatorValue(prop->key()); |
1765 __ movq(rcx, rax); | 1775 __ movq(rcx, rax); |
1766 __ pop(rdx); | 1776 __ pop(rdx); |
1767 } | 1777 } |
1768 __ pop(rax); // Restore value. | 1778 __ pop(rax); // Restore value. |
1769 Handle<Code> ic(Builtins::builtin( | 1779 Handle<Code> ic(isolate()->builtins()->builtin( |
1770 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1780 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
1771 : Builtins::KeyedStoreIC_Initialize)); | 1781 : Builtins::KeyedStoreIC_Initialize)); |
1772 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1782 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1773 break; | 1783 break; |
1774 } | 1784 } |
1775 } | 1785 } |
1776 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1786 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1777 context()->Plug(rax); | 1787 context()->Plug(rax); |
1778 } | 1788 } |
1779 | 1789 |
1780 | 1790 |
1781 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1791 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1782 Token::Value op) { | 1792 Token::Value op) { |
1783 // Left-hand sides that rewrite to explicit property accesses do not reach | 1793 // Left-hand sides that rewrite to explicit property accesses do not reach |
1784 // here. | 1794 // here. |
1785 ASSERT(var != NULL); | 1795 ASSERT(var != NULL); |
1786 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1796 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1787 | 1797 |
1788 if (var->is_global()) { | 1798 if (var->is_global()) { |
1789 ASSERT(!var->is_this()); | 1799 ASSERT(!var->is_this()); |
1790 // Assignment to a global variable. Use inline caching for the | 1800 // Assignment to a global variable. Use inline caching for the |
1791 // assignment. Right-hand-side value is passed in rax, variable name in | 1801 // assignment. Right-hand-side value is passed in rax, variable name in |
1792 // rcx, and the global object on the stack. | 1802 // rcx, and the global object on the stack. |
1793 __ Move(rcx, var->name()); | 1803 __ Move(rcx, var->name()); |
1794 __ movq(rdx, GlobalObjectOperand()); | 1804 __ movq(rdx, GlobalObjectOperand()); |
1795 Handle<Code> ic(Builtins::builtin( | 1805 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
1796 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1806 ? Builtins::StoreIC_Initialize_Strict |
1797 : Builtins::StoreIC_Initialize)); | 1807 : Builtins::StoreIC_Initialize)); |
1798 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1808 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1799 | 1809 |
1800 } else if (op == Token::INIT_CONST) { | 1810 } else if (op == Token::INIT_CONST) { |
1801 // Like var declarations, const declarations are hoisted to function | 1811 // Like var declarations, const declarations are hoisted to function |
1802 // scope. However, unlike var initializers, const initializers are able | 1812 // scope. However, unlike var initializers, const initializers are able |
1803 // to drill a hole to that function context, even from inside a 'with' | 1813 // to drill a hole to that function context, even from inside a 'with' |
1804 // context. We thus bypass the normal static scope lookup. | 1814 // context. We thus bypass the normal static scope lookup. |
1805 Slot* slot = var->AsSlot(); | 1815 Slot* slot = var->AsSlot(); |
1806 Label skip; | 1816 Label skip; |
1807 switch (slot->type()) { | 1817 switch (slot->type()) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1888 } | 1898 } |
1889 | 1899 |
1890 // Record source code position before IC call. | 1900 // Record source code position before IC call. |
1891 SetSourcePosition(expr->position()); | 1901 SetSourcePosition(expr->position()); |
1892 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1902 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1893 if (expr->ends_initialization_block()) { | 1903 if (expr->ends_initialization_block()) { |
1894 __ movq(rdx, Operand(rsp, 0)); | 1904 __ movq(rdx, Operand(rsp, 0)); |
1895 } else { | 1905 } else { |
1896 __ pop(rdx); | 1906 __ pop(rdx); |
1897 } | 1907 } |
1898 Handle<Code> ic(Builtins::builtin( | 1908 Handle<Code> ic(isolate()->builtins()->builtin( |
1899 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1909 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1900 : Builtins::StoreIC_Initialize)); | 1910 : Builtins::StoreIC_Initialize)); |
1901 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1911 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1902 | 1912 |
1903 // If the assignment ends an initialization block, revert to fast case. | 1913 // If the assignment ends an initialization block, revert to fast case. |
1904 if (expr->ends_initialization_block()) { | 1914 if (expr->ends_initialization_block()) { |
1905 __ push(rax); // Result of assignment, saved even if not needed. | 1915 __ push(rax); // Result of assignment, saved even if not needed. |
1906 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1916 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
1907 __ CallRuntime(Runtime::kToFastProperties, 1); | 1917 __ CallRuntime(Runtime::kToFastProperties, 1); |
1908 __ pop(rax); | 1918 __ pop(rax); |
(...skipping 19 matching lines...) Expand all Loading... |
1928 } | 1938 } |
1929 | 1939 |
1930 __ pop(rcx); | 1940 __ pop(rcx); |
1931 if (expr->ends_initialization_block()) { | 1941 if (expr->ends_initialization_block()) { |
1932 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. | 1942 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
1933 } else { | 1943 } else { |
1934 __ pop(rdx); | 1944 __ pop(rdx); |
1935 } | 1945 } |
1936 // Record source code position before IC call. | 1946 // Record source code position before IC call. |
1937 SetSourcePosition(expr->position()); | 1947 SetSourcePosition(expr->position()); |
1938 Handle<Code> ic(Builtins::builtin( | 1948 Handle<Code> ic(isolate()->builtins()->builtin( |
1939 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1949 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
1940 : Builtins::KeyedStoreIC_Initialize)); | 1950 : Builtins::KeyedStoreIC_Initialize)); |
1941 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1951 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1942 | 1952 |
1943 // If the assignment ends an initialization block, revert to fast case. | 1953 // If the assignment ends an initialization block, revert to fast case. |
1944 if (expr->ends_initialization_block()) { | 1954 if (expr->ends_initialization_block()) { |
1945 __ pop(rdx); | 1955 __ pop(rdx); |
1946 __ push(rax); // Result of assignment, saved even if not needed. | 1956 __ push(rax); // Result of assignment, saved even if not needed. |
1947 __ push(rdx); | 1957 __ push(rdx); |
1948 __ CallRuntime(Runtime::kToFastProperties, 1); | 1958 __ CallRuntime(Runtime::kToFastProperties, 1); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 { PreservePositionScope scope(masm()->positions_recorder()); | 1991 { PreservePositionScope scope(masm()->positions_recorder()); |
1982 for (int i = 0; i < arg_count; i++) { | 1992 for (int i = 0; i < arg_count; i++) { |
1983 VisitForStackValue(args->at(i)); | 1993 VisitForStackValue(args->at(i)); |
1984 } | 1994 } |
1985 __ Move(rcx, name); | 1995 __ Move(rcx, name); |
1986 } | 1996 } |
1987 // Record source position for debugger. | 1997 // Record source position for debugger. |
1988 SetSourcePosition(expr->position()); | 1998 SetSourcePosition(expr->position()); |
1989 // Call the IC initialization code. | 1999 // Call the IC initialization code. |
1990 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2000 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1991 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); | 2001 Handle<Code> ic = |
| 2002 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
1992 EmitCallIC(ic, mode); | 2003 EmitCallIC(ic, mode); |
1993 RecordJSReturnSite(expr); | 2004 RecordJSReturnSite(expr); |
1994 // Restore context register. | 2005 // Restore context register. |
1995 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2006 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1996 context()->Plug(rax); | 2007 context()->Plug(rax); |
1997 } | 2008 } |
1998 | 2009 |
1999 | 2010 |
2000 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2011 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2001 Expression* key, | 2012 Expression* key, |
(...skipping 12 matching lines...) Expand all Loading... |
2014 int arg_count = args->length(); | 2025 int arg_count = args->length(); |
2015 { PreservePositionScope scope(masm()->positions_recorder()); | 2026 { PreservePositionScope scope(masm()->positions_recorder()); |
2016 for (int i = 0; i < arg_count; i++) { | 2027 for (int i = 0; i < arg_count; i++) { |
2017 VisitForStackValue(args->at(i)); | 2028 VisitForStackValue(args->at(i)); |
2018 } | 2029 } |
2019 } | 2030 } |
2020 // Record source position for debugger. | 2031 // Record source position for debugger. |
2021 SetSourcePosition(expr->position()); | 2032 SetSourcePosition(expr->position()); |
2022 // Call the IC initialization code. | 2033 // Call the IC initialization code. |
2023 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2034 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2024 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); | 2035 Handle<Code> ic = |
| 2036 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
2025 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 2037 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
2026 EmitCallIC(ic, mode); | 2038 EmitCallIC(ic, mode); |
2027 RecordJSReturnSite(expr); | 2039 RecordJSReturnSite(expr); |
2028 // Restore context register. | 2040 // Restore context register. |
2029 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2041 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2030 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 2042 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
2031 } | 2043 } |
2032 | 2044 |
2033 | 2045 |
2034 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2046 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 MemOperand operand = EmitSlotSearch(slot, rdx); | 2219 MemOperand operand = EmitSlotSearch(slot, rdx); |
2208 __ movq(rdx, operand); | 2220 __ movq(rdx, operand); |
2209 | 2221 |
2210 ASSERT(prop->key()->AsLiteral() != NULL); | 2222 ASSERT(prop->key()->AsLiteral() != NULL); |
2211 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2223 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2212 __ Move(rax, prop->key()->AsLiteral()->handle()); | 2224 __ Move(rax, prop->key()->AsLiteral()->handle()); |
2213 | 2225 |
2214 // Record source code position for IC call. | 2226 // Record source code position for IC call. |
2215 SetSourcePosition(prop->position()); | 2227 SetSourcePosition(prop->position()); |
2216 | 2228 |
2217 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 2229 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2230 Builtins::KeyedLoadIC_Initialize)); |
2218 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2231 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2219 // Push result (function). | 2232 // Push result (function). |
2220 __ push(rax); | 2233 __ push(rax); |
2221 // Push Global receiver. | 2234 // Push Global receiver. |
2222 __ movq(rcx, GlobalObjectOperand()); | 2235 __ movq(rcx, GlobalObjectOperand()); |
2223 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 2236 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
2224 EmitCallWithStub(expr); | 2237 EmitCallWithStub(expr); |
2225 } else { | 2238 } else { |
2226 { PreservePositionScope scope(masm()->positions_recorder()); | 2239 { PreservePositionScope scope(masm()->positions_recorder()); |
2227 VisitForStackValue(prop->obj()); | 2240 VisitForStackValue(prop->obj()); |
2228 } | 2241 } |
2229 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2242 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
2230 } | 2243 } |
2231 } | 2244 } |
2232 } else { | 2245 } else { |
2233 // Call to some other expression. If the expression is an anonymous | 2246 // Call to some other expression. If the expression is an anonymous |
2234 // function literal not called in a loop, mark it as one that should | 2247 // function literal not called in a loop, mark it as one that should |
2235 // also use the full code generator. | 2248 // also use the full code generator. |
2236 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 2249 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
2237 if (lit != NULL && | 2250 if (lit != NULL && |
2238 lit->name()->Equals(Heap::empty_string()) && | 2251 lit->name()->Equals(isolate()->heap()->empty_string()) && |
2239 loop_depth() == 0) { | 2252 loop_depth() == 0) { |
2240 lit->set_try_full_codegen(true); | 2253 lit->set_try_full_codegen(true); |
2241 } | 2254 } |
2242 { PreservePositionScope scope(masm()->positions_recorder()); | 2255 { PreservePositionScope scope(masm()->positions_recorder()); |
2243 VisitForStackValue(fun); | 2256 VisitForStackValue(fun); |
2244 } | 2257 } |
2245 // Load global receiver object. | 2258 // Load global receiver object. |
2246 __ movq(rbx, GlobalObjectOperand()); | 2259 __ movq(rbx, GlobalObjectOperand()); |
2247 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 2260 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
2248 // Emit function call. | 2261 // Emit function call. |
(...skipping 26 matching lines...) Expand all Loading... |
2275 } | 2288 } |
2276 | 2289 |
2277 // Call the construct call builtin that handles allocation and | 2290 // Call the construct call builtin that handles allocation and |
2278 // constructor invocation. | 2291 // constructor invocation. |
2279 SetSourcePosition(expr->position()); | 2292 SetSourcePosition(expr->position()); |
2280 | 2293 |
2281 // Load function and argument count into rdi and rax. | 2294 // Load function and argument count into rdi and rax. |
2282 __ Set(rax, arg_count); | 2295 __ Set(rax, arg_count); |
2283 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); | 2296 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); |
2284 | 2297 |
2285 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 2298 Handle<Code> construct_builtin(isolate()->builtins()->builtin( |
| 2299 Builtins::JSConstructCall)); |
2286 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2300 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
2287 context()->Plug(rax); | 2301 context()->Plug(rax); |
2288 } | 2302 } |
2289 | 2303 |
2290 | 2304 |
2291 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2305 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
2292 ASSERT(args->length() == 1); | 2306 ASSERT(args->length() == 1); |
2293 | 2307 |
2294 VisitForAccumulatorValue(args->at(0)); | 2308 VisitForAccumulatorValue(args->at(0)); |
2295 | 2309 |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2608 __ j(not_equal, &non_function_constructor); | 2622 __ j(not_equal, &non_function_constructor); |
2609 | 2623 |
2610 // rax now contains the constructor function. Grab the | 2624 // rax now contains the constructor function. Grab the |
2611 // instance class name from there. | 2625 // instance class name from there. |
2612 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); | 2626 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); |
2613 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); | 2627 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); |
2614 __ jmp(&done); | 2628 __ jmp(&done); |
2615 | 2629 |
2616 // Functions have class 'Function'. | 2630 // Functions have class 'Function'. |
2617 __ bind(&function); | 2631 __ bind(&function); |
2618 __ Move(rax, Factory::function_class_symbol()); | 2632 __ Move(rax, isolate()->factory()->function_class_symbol()); |
2619 __ jmp(&done); | 2633 __ jmp(&done); |
2620 | 2634 |
2621 // Objects with a non-function constructor have class 'Object'. | 2635 // Objects with a non-function constructor have class 'Object'. |
2622 __ bind(&non_function_constructor); | 2636 __ bind(&non_function_constructor); |
2623 __ Move(rax, Factory::Object_symbol()); | 2637 __ Move(rax, isolate()->factory()->Object_symbol()); |
2624 __ jmp(&done); | 2638 __ jmp(&done); |
2625 | 2639 |
2626 // Non-JS objects have class null. | 2640 // Non-JS objects have class null. |
2627 __ bind(&null); | 2641 __ bind(&null); |
2628 __ LoadRoot(rax, Heap::kNullValueRootIndex); | 2642 __ LoadRoot(rax, Heap::kNullValueRootIndex); |
2629 | 2643 |
2630 // All done. | 2644 // All done. |
2631 __ bind(&done); | 2645 __ bind(&done); |
2632 | 2646 |
2633 context()->Plug(rax); | 2647 context()->Plug(rax); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3072 } | 3086 } |
3073 | 3087 |
3074 | 3088 |
3075 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { | 3089 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { |
3076 ASSERT_EQ(2, args->length()); | 3090 ASSERT_EQ(2, args->length()); |
3077 | 3091 |
3078 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3092 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
3079 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3093 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
3080 | 3094 |
3081 Handle<FixedArray> jsfunction_result_caches( | 3095 Handle<FixedArray> jsfunction_result_caches( |
3082 Top::global_context()->jsfunction_result_caches()); | 3096 isolate()->global_context()->jsfunction_result_caches()); |
3083 if (jsfunction_result_caches->length() <= cache_id) { | 3097 if (jsfunction_result_caches->length() <= cache_id) { |
3084 __ Abort("Attempt to use undefined cache."); | 3098 __ Abort("Attempt to use undefined cache."); |
3085 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 3099 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
3086 context()->Plug(rax); | 3100 context()->Plug(rax); |
3087 return; | 3101 return; |
3088 } | 3102 } |
3089 | 3103 |
3090 VisitForAccumulatorValue(args->at(1)); | 3104 VisitForAccumulatorValue(args->at(1)); |
3091 | 3105 |
3092 Register key = rax; | 3106 Register key = rax; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3149 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); | 3163 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); |
3150 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), | 3164 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), |
3151 Immediate(JS_REGEXP_TYPE)); | 3165 Immediate(JS_REGEXP_TYPE)); |
3152 __ j(not_equal, &fail); | 3166 __ j(not_equal, &fail); |
3153 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset)); | 3167 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset)); |
3154 __ j(not_equal, &fail); | 3168 __ j(not_equal, &fail); |
3155 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset)); | 3169 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset)); |
3156 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset)); | 3170 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset)); |
3157 __ j(equal, &ok); | 3171 __ j(equal, &ok); |
3158 __ bind(&fail); | 3172 __ bind(&fail); |
3159 __ Move(rax, Factory::false_value()); | 3173 __ Move(rax, isolate()->factory()->false_value()); |
3160 __ jmp(&done); | 3174 __ jmp(&done); |
3161 __ bind(&ok); | 3175 __ bind(&ok); |
3162 __ Move(rax, Factory::true_value()); | 3176 __ Move(rax, isolate()->factory()->true_value()); |
3163 __ bind(&done); | 3177 __ bind(&done); |
3164 | 3178 |
3165 context()->Plug(rax); | 3179 context()->Plug(rax); |
3166 } | 3180 } |
3167 | 3181 |
3168 | 3182 |
3169 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { | 3183 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { |
3170 ASSERT(args->length() == 1); | 3184 ASSERT(args->length() == 1); |
3171 | 3185 |
3172 VisitForAccumulatorValue(args->at(0)); | 3186 VisitForAccumulatorValue(args->at(0)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3229 // Push the arguments ("left-to-right"). | 3243 // Push the arguments ("left-to-right"). |
3230 int arg_count = args->length(); | 3244 int arg_count = args->length(); |
3231 for (int i = 0; i < arg_count; i++) { | 3245 for (int i = 0; i < arg_count; i++) { |
3232 VisitForStackValue(args->at(i)); | 3246 VisitForStackValue(args->at(i)); |
3233 } | 3247 } |
3234 | 3248 |
3235 if (expr->is_jsruntime()) { | 3249 if (expr->is_jsruntime()) { |
3236 // Call the JS runtime function using a call IC. | 3250 // Call the JS runtime function using a call IC. |
3237 __ Move(rcx, expr->name()); | 3251 __ Move(rcx, expr->name()); |
3238 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 3252 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
3239 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); | 3253 Handle<Code> ic = |
| 3254 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
3240 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3255 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3241 // Restore context register. | 3256 // Restore context register. |
3242 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3257 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
3243 } else { | 3258 } else { |
3244 __ CallRuntime(expr->function(), arg_count); | 3259 __ CallRuntime(expr->function(), arg_count); |
3245 } | 3260 } |
3246 context()->Plug(rax); | 3261 context()->Plug(rax); |
3247 } | 3262 } |
3248 | 3263 |
3249 | 3264 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3541 // Perform the assignment as if via '='. | 3556 // Perform the assignment as if via '='. |
3542 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3557 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3543 Token::ASSIGN); | 3558 Token::ASSIGN); |
3544 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3559 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3545 context()->Plug(rax); | 3560 context()->Plug(rax); |
3546 } | 3561 } |
3547 break; | 3562 break; |
3548 case NAMED_PROPERTY: { | 3563 case NAMED_PROPERTY: { |
3549 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 3564 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
3550 __ pop(rdx); | 3565 __ pop(rdx); |
3551 Handle<Code> ic(Builtins::builtin( | 3566 Handle<Code> ic(isolate()->builtins()->builtin( |
3552 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 3567 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
3553 : Builtins::StoreIC_Initialize)); | 3568 : Builtins::StoreIC_Initialize)); |
3554 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3569 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3555 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3570 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3556 if (expr->is_postfix()) { | 3571 if (expr->is_postfix()) { |
3557 if (!context()->IsEffect()) { | 3572 if (!context()->IsEffect()) { |
3558 context()->PlugTOS(); | 3573 context()->PlugTOS(); |
3559 } | 3574 } |
3560 } else { | 3575 } else { |
3561 context()->Plug(rax); | 3576 context()->Plug(rax); |
3562 } | 3577 } |
3563 break; | 3578 break; |
3564 } | 3579 } |
3565 case KEYED_PROPERTY: { | 3580 case KEYED_PROPERTY: { |
3566 __ pop(rcx); | 3581 __ pop(rcx); |
3567 __ pop(rdx); | 3582 __ pop(rdx); |
3568 Handle<Code> ic(Builtins::builtin( | 3583 Handle<Code> ic(isolate()->builtins()->builtin( |
3569 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 3584 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
3570 : Builtins::KeyedStoreIC_Initialize)); | 3585 : Builtins::KeyedStoreIC_Initialize)); |
3571 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3586 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3572 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3587 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3573 if (expr->is_postfix()) { | 3588 if (expr->is_postfix()) { |
3574 if (!context()->IsEffect()) { | 3589 if (!context()->IsEffect()) { |
3575 context()->PlugTOS(); | 3590 context()->PlugTOS(); |
3576 } | 3591 } |
3577 } else { | 3592 } else { |
3578 context()->Plug(rax); | 3593 context()->Plug(rax); |
3579 } | 3594 } |
3580 break; | 3595 break; |
3581 } | 3596 } |
3582 } | 3597 } |
3583 } | 3598 } |
3584 | 3599 |
3585 | 3600 |
3586 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3601 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3587 VariableProxy* proxy = expr->AsVariableProxy(); | 3602 VariableProxy* proxy = expr->AsVariableProxy(); |
3588 ASSERT(!context()->IsEffect()); | 3603 ASSERT(!context()->IsEffect()); |
3589 ASSERT(!context()->IsTest()); | 3604 ASSERT(!context()->IsTest()); |
3590 | 3605 |
3591 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3606 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3592 Comment cmnt(masm_, "Global variable"); | 3607 Comment cmnt(masm_, "Global variable"); |
3593 __ Move(rcx, proxy->name()); | 3608 __ Move(rcx, proxy->name()); |
3594 __ movq(rax, GlobalObjectOperand()); | 3609 __ movq(rax, GlobalObjectOperand()); |
3595 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3610 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3611 Builtins::LoadIC_Initialize)); |
3596 // Use a regular load, not a contextual load, to avoid a reference | 3612 // Use a regular load, not a contextual load, to avoid a reference |
3597 // error. | 3613 // error. |
3598 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3614 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3599 PrepareForBailout(expr, TOS_REG); | 3615 PrepareForBailout(expr, TOS_REG); |
3600 context()->Plug(rax); | 3616 context()->Plug(rax); |
3601 } else if (proxy != NULL && | 3617 } else if (proxy != NULL && |
3602 proxy->var()->AsSlot() != NULL && | 3618 proxy->var()->AsSlot() != NULL && |
3603 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3619 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3604 Label done, slow; | 3620 Label done, slow; |
3605 | 3621 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3638 if (!right_literal_value->IsString()) return false; | 3654 if (!right_literal_value->IsString()) return false; |
3639 UnaryOperation* left_unary = left->AsUnaryOperation(); | 3655 UnaryOperation* left_unary = left->AsUnaryOperation(); |
3640 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; | 3656 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; |
3641 Handle<String> check = Handle<String>::cast(right_literal_value); | 3657 Handle<String> check = Handle<String>::cast(right_literal_value); |
3642 | 3658 |
3643 { AccumulatorValueContext context(this); | 3659 { AccumulatorValueContext context(this); |
3644 VisitForTypeofValue(left_unary->expression()); | 3660 VisitForTypeofValue(left_unary->expression()); |
3645 } | 3661 } |
3646 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3662 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
3647 | 3663 |
3648 if (check->Equals(Heap::number_symbol())) { | 3664 if (check->Equals(isolate()->heap()->number_symbol())) { |
3649 __ JumpIfSmi(rax, if_true); | 3665 __ JumpIfSmi(rax, if_true); |
3650 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); | 3666 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); |
3651 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); | 3667 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); |
3652 Split(equal, if_true, if_false, fall_through); | 3668 Split(equal, if_true, if_false, fall_through); |
3653 } else if (check->Equals(Heap::string_symbol())) { | 3669 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
3654 __ JumpIfSmi(rax, if_false); | 3670 __ JumpIfSmi(rax, if_false); |
3655 // Check for undetectable objects => false. | 3671 // Check for undetectable objects => false. |
3656 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); | 3672 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); |
3657 __ j(above_equal, if_false); | 3673 __ j(above_equal, if_false); |
3658 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), | 3674 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), |
3659 Immediate(1 << Map::kIsUndetectable)); | 3675 Immediate(1 << Map::kIsUndetectable)); |
3660 Split(zero, if_true, if_false, fall_through); | 3676 Split(zero, if_true, if_false, fall_through); |
3661 } else if (check->Equals(Heap::boolean_symbol())) { | 3677 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { |
3662 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 3678 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
3663 __ j(equal, if_true); | 3679 __ j(equal, if_true); |
3664 __ CompareRoot(rax, Heap::kFalseValueRootIndex); | 3680 __ CompareRoot(rax, Heap::kFalseValueRootIndex); |
3665 Split(equal, if_true, if_false, fall_through); | 3681 Split(equal, if_true, if_false, fall_through); |
3666 } else if (check->Equals(Heap::undefined_symbol())) { | 3682 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { |
3667 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 3683 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
3668 __ j(equal, if_true); | 3684 __ j(equal, if_true); |
3669 __ JumpIfSmi(rax, if_false); | 3685 __ JumpIfSmi(rax, if_false); |
3670 // Check for undetectable objects => true. | 3686 // Check for undetectable objects => true. |
3671 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); | 3687 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); |
3672 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), | 3688 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), |
3673 Immediate(1 << Map::kIsUndetectable)); | 3689 Immediate(1 << Map::kIsUndetectable)); |
3674 Split(not_zero, if_true, if_false, fall_through); | 3690 Split(not_zero, if_true, if_false, fall_through); |
3675 } else if (check->Equals(Heap::function_symbol())) { | 3691 } else if (check->Equals(isolate()->heap()->function_symbol())) { |
3676 __ JumpIfSmi(rax, if_false); | 3692 __ JumpIfSmi(rax, if_false); |
3677 __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx); | 3693 __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx); |
3678 Split(above_equal, if_true, if_false, fall_through); | 3694 Split(above_equal, if_true, if_false, fall_through); |
3679 } else if (check->Equals(Heap::object_symbol())) { | 3695 } else if (check->Equals(isolate()->heap()->object_symbol())) { |
3680 __ JumpIfSmi(rax, if_false); | 3696 __ JumpIfSmi(rax, if_false); |
3681 __ CompareRoot(rax, Heap::kNullValueRootIndex); | 3697 __ CompareRoot(rax, Heap::kNullValueRootIndex); |
3682 __ j(equal, if_true); | 3698 __ j(equal, if_true); |
3683 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx); | 3699 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx); |
3684 __ j(below, if_false); | 3700 __ j(below, if_false); |
3685 __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE); | 3701 __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE); |
3686 __ j(above_equal, if_false); | 3702 __ j(above_equal, if_false); |
3687 // Check for undetectable objects => false. | 3703 // Check for undetectable objects => false. |
3688 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), | 3704 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), |
3689 Immediate(1 << Map::kIsUndetectable)); | 3705 Immediate(1 << Map::kIsUndetectable)); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3851 Register FullCodeGenerator::context_register() { | 3867 Register FullCodeGenerator::context_register() { |
3852 return rsi; | 3868 return rsi; |
3853 } | 3869 } |
3854 | 3870 |
3855 | 3871 |
3856 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { | 3872 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { |
3857 ASSERT(mode == RelocInfo::CODE_TARGET || | 3873 ASSERT(mode == RelocInfo::CODE_TARGET || |
3858 mode == RelocInfo::CODE_TARGET_CONTEXT); | 3874 mode == RelocInfo::CODE_TARGET_CONTEXT); |
3859 switch (ic->kind()) { | 3875 switch (ic->kind()) { |
3860 case Code::LOAD_IC: | 3876 case Code::LOAD_IC: |
3861 __ IncrementCounter(&Counters::named_load_full, 1); | 3877 __ IncrementCounter(COUNTERS->named_load_full(), 1); |
3862 break; | 3878 break; |
3863 case Code::KEYED_LOAD_IC: | 3879 case Code::KEYED_LOAD_IC: |
3864 __ IncrementCounter(&Counters::keyed_load_full, 1); | 3880 __ IncrementCounter(COUNTERS->keyed_load_full(), 1); |
3865 break; | 3881 break; |
3866 case Code::STORE_IC: | 3882 case Code::STORE_IC: |
3867 __ IncrementCounter(&Counters::named_store_full, 1); | 3883 __ IncrementCounter(COUNTERS->named_store_full(), 1); |
3868 break; | 3884 break; |
3869 case Code::KEYED_STORE_IC: | 3885 case Code::KEYED_STORE_IC: |
3870 __ IncrementCounter(&Counters::keyed_store_full, 1); | 3886 __ IncrementCounter(COUNTERS->keyed_store_full(), 1); |
3871 default: | 3887 default: |
3872 break; | 3888 break; |
3873 } | 3889 } |
3874 | 3890 |
3875 __ call(ic, mode); | 3891 __ call(ic, mode); |
3876 | 3892 |
3877 // Crankshaft doesn't need patching of inlined loads and stores. | 3893 // Crankshaft doesn't need patching of inlined loads and stores. |
3878 // When compiling the snapshot we need to produce code that works | 3894 // When compiling the snapshot we need to produce code that works |
3879 // with and without Crankshaft. | 3895 // with and without Crankshaft. |
3880 if (V8::UseCrankshaft() && !Serializer::enabled()) { | 3896 if (V8::UseCrankshaft() && !Serializer::enabled()) { |
(...skipping 13 matching lines...) Expand all Loading... |
3894 default: | 3910 default: |
3895 // Do nothing. | 3911 // Do nothing. |
3896 break; | 3912 break; |
3897 } | 3913 } |
3898 } | 3914 } |
3899 | 3915 |
3900 | 3916 |
3901 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { | 3917 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { |
3902 switch (ic->kind()) { | 3918 switch (ic->kind()) { |
3903 case Code::LOAD_IC: | 3919 case Code::LOAD_IC: |
3904 __ IncrementCounter(&Counters::named_load_full, 1); | 3920 __ IncrementCounter(COUNTERS->named_load_full(), 1); |
3905 break; | 3921 break; |
3906 case Code::KEYED_LOAD_IC: | 3922 case Code::KEYED_LOAD_IC: |
3907 __ IncrementCounter(&Counters::keyed_load_full, 1); | 3923 __ IncrementCounter(COUNTERS->keyed_load_full(), 1); |
3908 break; | 3924 break; |
3909 case Code::STORE_IC: | 3925 case Code::STORE_IC: |
3910 __ IncrementCounter(&Counters::named_store_full, 1); | 3926 __ IncrementCounter(COUNTERS->named_store_full(), 1); |
3911 break; | 3927 break; |
3912 case Code::KEYED_STORE_IC: | 3928 case Code::KEYED_STORE_IC: |
3913 __ IncrementCounter(&Counters::keyed_store_full, 1); | 3929 __ IncrementCounter(COUNTERS->keyed_store_full(), 1); |
3914 default: | 3930 default: |
3915 break; | 3931 break; |
3916 } | 3932 } |
3917 | 3933 |
3918 __ call(ic, RelocInfo::CODE_TARGET); | 3934 __ call(ic, RelocInfo::CODE_TARGET); |
3919 if (patch_site != NULL && patch_site->is_bound()) { | 3935 if (patch_site != NULL && patch_site->is_bound()) { |
3920 patch_site->EmitPatchInfo(); | 3936 patch_site->EmitPatchInfo(); |
3921 } else { | 3937 } else { |
3922 __ nop(); // Signals no inlined code. | 3938 __ nop(); // Signals no inlined code. |
3923 } | 3939 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3968 __ ret(0); | 3984 __ ret(0); |
3969 } | 3985 } |
3970 | 3986 |
3971 | 3987 |
3972 #undef __ | 3988 #undef __ |
3973 | 3989 |
3974 | 3990 |
3975 } } // namespace v8::internal | 3991 } } // namespace v8::internal |
3976 | 3992 |
3977 #endif // V8_TARGET_ARCH_X64 | 3993 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |