Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 6880010: Merge (7265, 7271] from bleeding_edge to experimental/gc branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 } 1899 }
1890 1900
1891 // Record source code position before IC call. 1901 // Record source code position before IC call.
1892 SetSourcePosition(expr->position()); 1902 SetSourcePosition(expr->position());
1893 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1903 __ Move(rcx, prop->key()->AsLiteral()->handle());
1894 if (expr->ends_initialization_block()) { 1904 if (expr->ends_initialization_block()) {
1895 __ movq(rdx, Operand(rsp, 0)); 1905 __ movq(rdx, Operand(rsp, 0));
1896 } else { 1906 } else {
1897 __ pop(rdx); 1907 __ pop(rdx);
1898 } 1908 }
1899 Handle<Code> ic(Builtins::builtin( 1909 Handle<Code> ic(isolate()->builtins()->builtin(
1900 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 1910 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
1901 : Builtins::StoreIC_Initialize)); 1911 : Builtins::StoreIC_Initialize));
1902 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1912 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1903 1913
1904 // If the assignment ends an initialization block, revert to fast case. 1914 // If the assignment ends an initialization block, revert to fast case.
1905 if (expr->ends_initialization_block()) { 1915 if (expr->ends_initialization_block()) {
1906 __ push(rax); // Result of assignment, saved even if not needed. 1916 __ push(rax); // Result of assignment, saved even if not needed.
1907 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1917 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1908 __ CallRuntime(Runtime::kToFastProperties, 1); 1918 __ CallRuntime(Runtime::kToFastProperties, 1);
1909 __ pop(rax); 1919 __ pop(rax);
(...skipping 19 matching lines...) Expand all
1929 } 1939 }
1930 1940
1931 __ pop(rcx); 1941 __ pop(rcx);
1932 if (expr->ends_initialization_block()) { 1942 if (expr->ends_initialization_block()) {
1933 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. 1943 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
1934 } else { 1944 } else {
1935 __ pop(rdx); 1945 __ pop(rdx);
1936 } 1946 }
1937 // Record source code position before IC call. 1947 // Record source code position before IC call.
1938 SetSourcePosition(expr->position()); 1948 SetSourcePosition(expr->position());
1939 Handle<Code> ic(Builtins::builtin( 1949 Handle<Code> ic(isolate()->builtins()->builtin(
1940 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 1950 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
1941 : Builtins::KeyedStoreIC_Initialize)); 1951 : Builtins::KeyedStoreIC_Initialize));
1942 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1952 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1943 1953
1944 // If the assignment ends an initialization block, revert to fast case. 1954 // If the assignment ends an initialization block, revert to fast case.
1945 if (expr->ends_initialization_block()) { 1955 if (expr->ends_initialization_block()) {
1946 __ pop(rdx); 1956 __ pop(rdx);
1947 __ push(rax); // Result of assignment, saved even if not needed. 1957 __ push(rax); // Result of assignment, saved even if not needed.
1948 __ push(rdx); 1958 __ push(rdx);
1949 __ CallRuntime(Runtime::kToFastProperties, 1); 1959 __ CallRuntime(Runtime::kToFastProperties, 1);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 { PreservePositionScope scope(masm()->positions_recorder()); 1992 { PreservePositionScope scope(masm()->positions_recorder());
1983 for (int i = 0; i < arg_count; i++) { 1993 for (int i = 0; i < arg_count; i++) {
1984 VisitForStackValue(args->at(i)); 1994 VisitForStackValue(args->at(i));
1985 } 1995 }
1986 __ Move(rcx, name); 1996 __ Move(rcx, name);
1987 } 1997 }
1988 // Record source position for debugger. 1998 // Record source position for debugger.
1989 SetSourcePosition(expr->position()); 1999 SetSourcePosition(expr->position());
1990 // Call the IC initialization code. 2000 // Call the IC initialization code.
1991 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2001 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1992 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); 2002 Handle<Code> ic =
2003 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
1993 EmitCallIC(ic, mode); 2004 EmitCallIC(ic, mode);
1994 RecordJSReturnSite(expr); 2005 RecordJSReturnSite(expr);
1995 // Restore context register. 2006 // Restore context register.
1996 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2007 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1997 context()->Plug(rax); 2008 context()->Plug(rax);
1998 } 2009 }
1999 2010
2000 2011
2001 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2012 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2002 Expression* key, 2013 Expression* key,
(...skipping 12 matching lines...) Expand all
2015 int arg_count = args->length(); 2026 int arg_count = args->length();
2016 { PreservePositionScope scope(masm()->positions_recorder()); 2027 { PreservePositionScope scope(masm()->positions_recorder());
2017 for (int i = 0; i < arg_count; i++) { 2028 for (int i = 0; i < arg_count; i++) {
2018 VisitForStackValue(args->at(i)); 2029 VisitForStackValue(args->at(i));
2019 } 2030 }
2020 } 2031 }
2021 // Record source position for debugger. 2032 // Record source position for debugger.
2022 SetSourcePosition(expr->position()); 2033 SetSourcePosition(expr->position());
2023 // Call the IC initialization code. 2034 // Call the IC initialization code.
2024 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2035 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2025 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); 2036 Handle<Code> ic =
2037 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
2026 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. 2038 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key.
2027 EmitCallIC(ic, mode); 2039 EmitCallIC(ic, mode);
2028 RecordJSReturnSite(expr); 2040 RecordJSReturnSite(expr);
2029 // Restore context register. 2041 // Restore context register.
2030 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2042 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2031 context()->DropAndPlug(1, rax); // Drop the key still on the stack. 2043 context()->DropAndPlug(1, rax); // Drop the key still on the stack.
2032 } 2044 }
2033 2045
2034 2046
2035 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2047 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2208 MemOperand operand = EmitSlotSearch(slot, rdx); 2220 MemOperand operand = EmitSlotSearch(slot, rdx);
2209 __ movq(rdx, operand); 2221 __ movq(rdx, operand);
2210 2222
2211 ASSERT(prop->key()->AsLiteral() != NULL); 2223 ASSERT(prop->key()->AsLiteral() != NULL);
2212 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2224 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2213 __ Move(rax, prop->key()->AsLiteral()->handle()); 2225 __ Move(rax, prop->key()->AsLiteral()->handle());
2214 2226
2215 // Record source code position for IC call. 2227 // Record source code position for IC call.
2216 SetSourcePosition(prop->position()); 2228 SetSourcePosition(prop->position());
2217 2229
2218 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 2230 Handle<Code> ic(isolate()->builtins()->builtin(
2231 Builtins::KeyedLoadIC_Initialize));
2219 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2232 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2220 // Push result (function). 2233 // Push result (function).
2221 __ push(rax); 2234 __ push(rax);
2222 // Push Global receiver. 2235 // Push Global receiver.
2223 __ movq(rcx, GlobalObjectOperand()); 2236 __ movq(rcx, GlobalObjectOperand());
2224 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 2237 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
2225 EmitCallWithStub(expr); 2238 EmitCallWithStub(expr);
2226 } else { 2239 } else {
2227 { PreservePositionScope scope(masm()->positions_recorder()); 2240 { PreservePositionScope scope(masm()->positions_recorder());
2228 VisitForStackValue(prop->obj()); 2241 VisitForStackValue(prop->obj());
2229 } 2242 }
2230 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2243 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2231 } 2244 }
2232 } 2245 }
2233 } else { 2246 } else {
2234 // Call to some other expression. If the expression is an anonymous 2247 // Call to some other expression. If the expression is an anonymous
2235 // function literal not called in a loop, mark it as one that should 2248 // function literal not called in a loop, mark it as one that should
2236 // also use the full code generator. 2249 // also use the full code generator.
2237 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2250 FunctionLiteral* lit = fun->AsFunctionLiteral();
2238 if (lit != NULL && 2251 if (lit != NULL &&
2239 lit->name()->Equals(Heap::empty_string()) && 2252 lit->name()->Equals(isolate()->heap()->empty_string()) &&
2240 loop_depth() == 0) { 2253 loop_depth() == 0) {
2241 lit->set_try_full_codegen(true); 2254 lit->set_try_full_codegen(true);
2242 } 2255 }
2243 { PreservePositionScope scope(masm()->positions_recorder()); 2256 { PreservePositionScope scope(masm()->positions_recorder());
2244 VisitForStackValue(fun); 2257 VisitForStackValue(fun);
2245 } 2258 }
2246 // Load global receiver object. 2259 // Load global receiver object.
2247 __ movq(rbx, GlobalObjectOperand()); 2260 __ movq(rbx, GlobalObjectOperand());
2248 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); 2261 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
2249 // Emit function call. 2262 // Emit function call.
(...skipping 26 matching lines...) Expand all
2276 } 2289 }
2277 2290
2278 // Call the construct call builtin that handles allocation and 2291 // Call the construct call builtin that handles allocation and
2279 // constructor invocation. 2292 // constructor invocation.
2280 SetSourcePosition(expr->position()); 2293 SetSourcePosition(expr->position());
2281 2294
2282 // Load function and argument count into rdi and rax. 2295 // Load function and argument count into rdi and rax.
2283 __ Set(rax, arg_count); 2296 __ Set(rax, arg_count);
2284 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); 2297 __ movq(rdi, Operand(rsp, arg_count * kPointerSize));
2285 2298
2286 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 2299 Handle<Code> construct_builtin(isolate()->builtins()->builtin(
2300 Builtins::JSConstructCall));
2287 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2301 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2288 context()->Plug(rax); 2302 context()->Plug(rax);
2289 } 2303 }
2290 2304
2291 2305
2292 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2306 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2293 ASSERT(args->length() == 1); 2307 ASSERT(args->length() == 1);
2294 2308
2295 VisitForAccumulatorValue(args->at(0)); 2309 VisitForAccumulatorValue(args->at(0));
2296 2310
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 __ j(not_equal, &non_function_constructor); 2623 __ j(not_equal, &non_function_constructor);
2610 2624
2611 // rax now contains the constructor function. Grab the 2625 // rax now contains the constructor function. Grab the
2612 // instance class name from there. 2626 // instance class name from there.
2613 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); 2627 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
2614 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); 2628 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset));
2615 __ jmp(&done); 2629 __ jmp(&done);
2616 2630
2617 // Functions have class 'Function'. 2631 // Functions have class 'Function'.
2618 __ bind(&function); 2632 __ bind(&function);
2619 __ Move(rax, Factory::function_class_symbol()); 2633 __ Move(rax, isolate()->factory()->function_class_symbol());
2620 __ jmp(&done); 2634 __ jmp(&done);
2621 2635
2622 // Objects with a non-function constructor have class 'Object'. 2636 // Objects with a non-function constructor have class 'Object'.
2623 __ bind(&non_function_constructor); 2637 __ bind(&non_function_constructor);
2624 __ Move(rax, Factory::Object_symbol()); 2638 __ Move(rax, isolate()->factory()->Object_symbol());
2625 __ jmp(&done); 2639 __ jmp(&done);
2626 2640
2627 // Non-JS objects have class null. 2641 // Non-JS objects have class null.
2628 __ bind(&null); 2642 __ bind(&null);
2629 __ LoadRoot(rax, Heap::kNullValueRootIndex); 2643 __ LoadRoot(rax, Heap::kNullValueRootIndex);
2630 2644
2631 // All done. 2645 // All done.
2632 __ bind(&done); 2646 __ bind(&done);
2633 2647
2634 context()->Plug(rax); 2648 context()->Plug(rax);
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
3073 } 3087 }
3074 3088
3075 3089
3076 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3090 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3077 ASSERT_EQ(2, args->length()); 3091 ASSERT_EQ(2, args->length());
3078 3092
3079 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3093 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3080 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3094 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3081 3095
3082 Handle<FixedArray> jsfunction_result_caches( 3096 Handle<FixedArray> jsfunction_result_caches(
3083 Top::global_context()->jsfunction_result_caches()); 3097 isolate()->global_context()->jsfunction_result_caches());
3084 if (jsfunction_result_caches->length() <= cache_id) { 3098 if (jsfunction_result_caches->length() <= cache_id) {
3085 __ Abort("Attempt to use undefined cache."); 3099 __ Abort("Attempt to use undefined cache.");
3086 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 3100 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
3087 context()->Plug(rax); 3101 context()->Plug(rax);
3088 return; 3102 return;
3089 } 3103 }
3090 3104
3091 VisitForAccumulatorValue(args->at(1)); 3105 VisitForAccumulatorValue(args->at(1));
3092 3106
3093 Register key = rax; 3107 Register key = rax;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3150 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); 3164 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset));
3151 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), 3165 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset),
3152 Immediate(JS_REGEXP_TYPE)); 3166 Immediate(JS_REGEXP_TYPE));
3153 __ j(not_equal, &fail); 3167 __ j(not_equal, &fail);
3154 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset)); 3168 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset));
3155 __ j(not_equal, &fail); 3169 __ j(not_equal, &fail);
3156 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3170 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3157 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3171 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3158 __ j(equal, &ok); 3172 __ j(equal, &ok);
3159 __ bind(&fail); 3173 __ bind(&fail);
3160 __ Move(rax, Factory::false_value()); 3174 __ Move(rax, isolate()->factory()->false_value());
3161 __ jmp(&done); 3175 __ jmp(&done);
3162 __ bind(&ok); 3176 __ bind(&ok);
3163 __ Move(rax, Factory::true_value()); 3177 __ Move(rax, isolate()->factory()->true_value());
3164 __ bind(&done); 3178 __ bind(&done);
3165 3179
3166 context()->Plug(rax); 3180 context()->Plug(rax);
3167 } 3181 }
3168 3182
3169 3183
3170 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3184 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3171 ASSERT(args->length() == 1); 3185 ASSERT(args->length() == 1);
3172 3186
3173 VisitForAccumulatorValue(args->at(0)); 3187 VisitForAccumulatorValue(args->at(0));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3230 // Push the arguments ("left-to-right"). 3244 // Push the arguments ("left-to-right").
3231 int arg_count = args->length(); 3245 int arg_count = args->length();
3232 for (int i = 0; i < arg_count; i++) { 3246 for (int i = 0; i < arg_count; i++) {
3233 VisitForStackValue(args->at(i)); 3247 VisitForStackValue(args->at(i));
3234 } 3248 }
3235 3249
3236 if (expr->is_jsruntime()) { 3250 if (expr->is_jsruntime()) {
3237 // Call the JS runtime function using a call IC. 3251 // Call the JS runtime function using a call IC.
3238 __ Move(rcx, expr->name()); 3252 __ Move(rcx, expr->name());
3239 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3253 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3240 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); 3254 Handle<Code> ic =
3255 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
3241 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3256 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3242 // Restore context register. 3257 // Restore context register.
3243 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3258 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3244 } else { 3259 } else {
3245 __ CallRuntime(expr->function(), arg_count); 3260 __ CallRuntime(expr->function(), arg_count);
3246 } 3261 }
3247 context()->Plug(rax); 3262 context()->Plug(rax);
3248 } 3263 }
3249 3264
3250 3265
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3542 // Perform the assignment as if via '='. 3557 // Perform the assignment as if via '='.
3543 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3558 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3544 Token::ASSIGN); 3559 Token::ASSIGN);
3545 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3560 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3546 context()->Plug(rax); 3561 context()->Plug(rax);
3547 } 3562 }
3548 break; 3563 break;
3549 case NAMED_PROPERTY: { 3564 case NAMED_PROPERTY: {
3550 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3565 __ Move(rcx, prop->key()->AsLiteral()->handle());
3551 __ pop(rdx); 3566 __ pop(rdx);
3552 Handle<Code> ic(Builtins::builtin( 3567 Handle<Code> ic(isolate()->builtins()->builtin(
3553 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 3568 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
3554 : Builtins::StoreIC_Initialize)); 3569 : Builtins::StoreIC_Initialize));
3555 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3570 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3556 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3571 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3557 if (expr->is_postfix()) { 3572 if (expr->is_postfix()) {
3558 if (!context()->IsEffect()) { 3573 if (!context()->IsEffect()) {
3559 context()->PlugTOS(); 3574 context()->PlugTOS();
3560 } 3575 }
3561 } else { 3576 } else {
3562 context()->Plug(rax); 3577 context()->Plug(rax);
3563 } 3578 }
3564 break; 3579 break;
3565 } 3580 }
3566 case KEYED_PROPERTY: { 3581 case KEYED_PROPERTY: {
3567 __ pop(rcx); 3582 __ pop(rcx);
3568 __ pop(rdx); 3583 __ pop(rdx);
3569 Handle<Code> ic(Builtins::builtin( 3584 Handle<Code> ic(isolate()->builtins()->builtin(
3570 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 3585 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
3571 : Builtins::KeyedStoreIC_Initialize)); 3586 : Builtins::KeyedStoreIC_Initialize));
3572 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3587 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3573 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3588 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3574 if (expr->is_postfix()) { 3589 if (expr->is_postfix()) {
3575 if (!context()->IsEffect()) { 3590 if (!context()->IsEffect()) {
3576 context()->PlugTOS(); 3591 context()->PlugTOS();
3577 } 3592 }
3578 } else { 3593 } else {
3579 context()->Plug(rax); 3594 context()->Plug(rax);
3580 } 3595 }
3581 break; 3596 break;
3582 } 3597 }
3583 } 3598 }
3584 } 3599 }
3585 3600
3586 3601
3587 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3602 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3588 VariableProxy* proxy = expr->AsVariableProxy(); 3603 VariableProxy* proxy = expr->AsVariableProxy();
3589 ASSERT(!context()->IsEffect()); 3604 ASSERT(!context()->IsEffect());
3590 ASSERT(!context()->IsTest()); 3605 ASSERT(!context()->IsTest());
3591 3606
3592 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3607 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3593 Comment cmnt(masm_, "Global variable"); 3608 Comment cmnt(masm_, "Global variable");
3594 __ Move(rcx, proxy->name()); 3609 __ Move(rcx, proxy->name());
3595 __ movq(rax, GlobalObjectOperand()); 3610 __ movq(rax, GlobalObjectOperand());
3596 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3611 Handle<Code> ic(isolate()->builtins()->builtin(
3612 Builtins::LoadIC_Initialize));
3597 // Use a regular load, not a contextual load, to avoid a reference 3613 // Use a regular load, not a contextual load, to avoid a reference
3598 // error. 3614 // error.
3599 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3615 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3600 PrepareForBailout(expr, TOS_REG); 3616 PrepareForBailout(expr, TOS_REG);
3601 context()->Plug(rax); 3617 context()->Plug(rax);
3602 } else if (proxy != NULL && 3618 } else if (proxy != NULL &&
3603 proxy->var()->AsSlot() != NULL && 3619 proxy->var()->AsSlot() != NULL &&
3604 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3620 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3605 Label done, slow; 3621 Label done, slow;
3606 3622
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3639 if (!right_literal_value->IsString()) return false; 3655 if (!right_literal_value->IsString()) return false;
3640 UnaryOperation* left_unary = left->AsUnaryOperation(); 3656 UnaryOperation* left_unary = left->AsUnaryOperation();
3641 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; 3657 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
3642 Handle<String> check = Handle<String>::cast(right_literal_value); 3658 Handle<String> check = Handle<String>::cast(right_literal_value);
3643 3659
3644 { AccumulatorValueContext context(this); 3660 { AccumulatorValueContext context(this);
3645 VisitForTypeofValue(left_unary->expression()); 3661 VisitForTypeofValue(left_unary->expression());
3646 } 3662 }
3647 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3663 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3648 3664
3649 if (check->Equals(Heap::number_symbol())) { 3665 if (check->Equals(isolate()->heap()->number_symbol())) {
3650 __ JumpIfSmi(rax, if_true); 3666 __ JumpIfSmi(rax, if_true);
3651 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); 3667 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset));
3652 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); 3668 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex);
3653 Split(equal, if_true, if_false, fall_through); 3669 Split(equal, if_true, if_false, fall_through);
3654 } else if (check->Equals(Heap::string_symbol())) { 3670 } else if (check->Equals(isolate()->heap()->string_symbol())) {
3655 __ JumpIfSmi(rax, if_false); 3671 __ JumpIfSmi(rax, if_false);
3656 // Check for undetectable objects => false. 3672 // Check for undetectable objects => false.
3657 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 3673 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
3658 __ j(above_equal, if_false); 3674 __ j(above_equal, if_false);
3659 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3675 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3660 Immediate(1 << Map::kIsUndetectable)); 3676 Immediate(1 << Map::kIsUndetectable));
3661 Split(zero, if_true, if_false, fall_through); 3677 Split(zero, if_true, if_false, fall_through);
3662 } else if (check->Equals(Heap::boolean_symbol())) { 3678 } else if (check->Equals(isolate()->heap()->boolean_symbol())) {
3663 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 3679 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
3664 __ j(equal, if_true); 3680 __ j(equal, if_true);
3665 __ CompareRoot(rax, Heap::kFalseValueRootIndex); 3681 __ CompareRoot(rax, Heap::kFalseValueRootIndex);
3666 Split(equal, if_true, if_false, fall_through); 3682 Split(equal, if_true, if_false, fall_through);
3667 } else if (check->Equals(Heap::undefined_symbol())) { 3683 } else if (check->Equals(isolate()->heap()->undefined_symbol())) {
3668 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 3684 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
3669 __ j(equal, if_true); 3685 __ j(equal, if_true);
3670 __ JumpIfSmi(rax, if_false); 3686 __ JumpIfSmi(rax, if_false);
3671 // Check for undetectable objects => true. 3687 // Check for undetectable objects => true.
3672 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 3688 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
3673 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3689 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3674 Immediate(1 << Map::kIsUndetectable)); 3690 Immediate(1 << Map::kIsUndetectable));
3675 Split(not_zero, if_true, if_false, fall_through); 3691 Split(not_zero, if_true, if_false, fall_through);
3676 } else if (check->Equals(Heap::function_symbol())) { 3692 } else if (check->Equals(isolate()->heap()->function_symbol())) {
3677 __ JumpIfSmi(rax, if_false); 3693 __ JumpIfSmi(rax, if_false);
3678 __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx); 3694 __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx);
3679 Split(above_equal, if_true, if_false, fall_through); 3695 Split(above_equal, if_true, if_false, fall_through);
3680 } else if (check->Equals(Heap::object_symbol())) { 3696 } else if (check->Equals(isolate()->heap()->object_symbol())) {
3681 __ JumpIfSmi(rax, if_false); 3697 __ JumpIfSmi(rax, if_false);
3682 __ CompareRoot(rax, Heap::kNullValueRootIndex); 3698 __ CompareRoot(rax, Heap::kNullValueRootIndex);
3683 __ j(equal, if_true); 3699 __ j(equal, if_true);
3684 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx); 3700 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx);
3685 __ j(below, if_false); 3701 __ j(below, if_false);
3686 __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE); 3702 __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE);
3687 __ j(above_equal, if_false); 3703 __ j(above_equal, if_false);
3688 // Check for undetectable objects => false. 3704 // Check for undetectable objects => false.
3689 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3705 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3690 Immediate(1 << Map::kIsUndetectable)); 3706 Immediate(1 << Map::kIsUndetectable));
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3852 Register FullCodeGenerator::context_register() { 3868 Register FullCodeGenerator::context_register() {
3853 return rsi; 3869 return rsi;
3854 } 3870 }
3855 3871
3856 3872
3857 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 3873 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
3858 ASSERT(mode == RelocInfo::CODE_TARGET || 3874 ASSERT(mode == RelocInfo::CODE_TARGET ||
3859 mode == RelocInfo::CODE_TARGET_CONTEXT); 3875 mode == RelocInfo::CODE_TARGET_CONTEXT);
3860 switch (ic->kind()) { 3876 switch (ic->kind()) {
3861 case Code::LOAD_IC: 3877 case Code::LOAD_IC:
3862 __ IncrementCounter(&Counters::named_load_full, 1); 3878 __ IncrementCounter(COUNTERS->named_load_full(), 1);
3863 break; 3879 break;
3864 case Code::KEYED_LOAD_IC: 3880 case Code::KEYED_LOAD_IC:
3865 __ IncrementCounter(&Counters::keyed_load_full, 1); 3881 __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
3866 break; 3882 break;
3867 case Code::STORE_IC: 3883 case Code::STORE_IC:
3868 __ IncrementCounter(&Counters::named_store_full, 1); 3884 __ IncrementCounter(COUNTERS->named_store_full(), 1);
3869 break; 3885 break;
3870 case Code::KEYED_STORE_IC: 3886 case Code::KEYED_STORE_IC:
3871 __ IncrementCounter(&Counters::keyed_store_full, 1); 3887 __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
3872 default: 3888 default:
3873 break; 3889 break;
3874 } 3890 }
3875 3891
3876 __ call(ic, mode); 3892 __ call(ic, mode);
3877 3893
3878 // Crankshaft doesn't need patching of inlined loads and stores. 3894 // Crankshaft doesn't need patching of inlined loads and stores.
3879 // When compiling the snapshot we need to produce code that works 3895 // When compiling the snapshot we need to produce code that works
3880 // with and without Crankshaft. 3896 // with and without Crankshaft.
3881 if (V8::UseCrankshaft() && !Serializer::enabled()) { 3897 if (V8::UseCrankshaft() && !Serializer::enabled()) {
(...skipping 13 matching lines...) Expand all
3895 default: 3911 default:
3896 // Do nothing. 3912 // Do nothing.
3897 break; 3913 break;
3898 } 3914 }
3899 } 3915 }
3900 3916
3901 3917
3902 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 3918 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
3903 switch (ic->kind()) { 3919 switch (ic->kind()) {
3904 case Code::LOAD_IC: 3920 case Code::LOAD_IC:
3905 __ IncrementCounter(&Counters::named_load_full, 1); 3921 __ IncrementCounter(COUNTERS->named_load_full(), 1);
3906 break; 3922 break;
3907 case Code::KEYED_LOAD_IC: 3923 case Code::KEYED_LOAD_IC:
3908 __ IncrementCounter(&Counters::keyed_load_full, 1); 3924 __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
3909 break; 3925 break;
3910 case Code::STORE_IC: 3926 case Code::STORE_IC:
3911 __ IncrementCounter(&Counters::named_store_full, 1); 3927 __ IncrementCounter(COUNTERS->named_store_full(), 1);
3912 break; 3928 break;
3913 case Code::KEYED_STORE_IC: 3929 case Code::KEYED_STORE_IC:
3914 __ IncrementCounter(&Counters::keyed_store_full, 1); 3930 __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
3915 default: 3931 default:
3916 break; 3932 break;
3917 } 3933 }
3918 3934
3919 __ call(ic, RelocInfo::CODE_TARGET); 3935 __ call(ic, RelocInfo::CODE_TARGET);
3920 if (patch_site != NULL && patch_site->is_bound()) { 3936 if (patch_site != NULL && patch_site->is_bound()) {
3921 patch_site->EmitPatchInfo(); 3937 patch_site->EmitPatchInfo();
3922 } else { 3938 } else {
3923 __ nop(); // Signals no inlined code. 3939 __ nop(); // Signals no inlined code.
3924 } 3940 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3969 __ ret(0); 3985 __ ret(0);
3970 } 3986 }
3971 3987
3972 3988
3973 #undef __ 3989 #undef __
3974 3990
3975 3991
3976 } } // namespace v8::internal 3992 } } // namespace v8::internal
3977 3993
3978 #endif // V8_TARGET_ARCH_X64 3994 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/store-buffer.cc ('K') | « src/x64/frames-x64.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698