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

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

Issue 6542061: [Isolates] Less TLS reads in parser and full codegens. (Closed)
Patch Set: Created 9 years, 10 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
« no previous file with comments | « src/parser.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 ASSERT(materialize_true == materialize_false); 400 ASSERT(materialize_true == materialize_false);
401 __ bind(materialize_true); 401 __ bind(materialize_true);
402 } 402 }
403 403
404 404
405 void FullCodeGenerator::AccumulatorValueContext::Plug( 405 void FullCodeGenerator::AccumulatorValueContext::Plug(
406 Label* materialize_true, 406 Label* materialize_true,
407 Label* materialize_false) const { 407 Label* materialize_false) const {
408 NearLabel done; 408 NearLabel done;
409 __ bind(materialize_true); 409 __ bind(materialize_true);
410 __ Move(result_register(), FACTORY->true_value()); 410 __ Move(result_register(), isolate()->factory()->true_value());
411 __ jmp(&done); 411 __ jmp(&done);
412 __ bind(materialize_false); 412 __ bind(materialize_false);
413 __ Move(result_register(), FACTORY->false_value()); 413 __ Move(result_register(), isolate()->factory()->false_value());
414 __ bind(&done); 414 __ bind(&done);
415 } 415 }
416 416
417 417
418 void FullCodeGenerator::StackValueContext::Plug( 418 void FullCodeGenerator::StackValueContext::Plug(
419 Label* materialize_true, 419 Label* materialize_true,
420 Label* materialize_false) const { 420 Label* materialize_false) const {
421 NearLabel done; 421 NearLabel done;
422 __ bind(materialize_true); 422 __ bind(materialize_true);
423 __ Push(FACTORY->true_value()); 423 __ Push(isolate()->factory()->true_value());
424 __ jmp(&done); 424 __ jmp(&done);
425 __ bind(materialize_false); 425 __ bind(materialize_false);
426 __ Push(FACTORY->false_value()); 426 __ Push(isolate()->factory()->false_value());
427 __ bind(&done); 427 __ bind(&done);
428 } 428 }
429 429
430 430
431 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 431 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
432 Label* materialize_false) const { 432 Label* materialize_false) const {
433 ASSERT(materialize_true == true_label_); 433 ASSERT(materialize_true == true_label_);
434 ASSERT(materialize_false == false_label_); 434 ASSERT(materialize_false == false_label_);
435 } 435 }
436 436
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 VisitForStackValue(prop->key()); 631 VisitForStackValue(prop->key());
632 VisitForAccumulatorValue(function); 632 VisitForAccumulatorValue(function);
633 __ pop(rcx); 633 __ pop(rcx);
634 } else { 634 } else {
635 VisitForAccumulatorValue(prop->key()); 635 VisitForAccumulatorValue(prop->key());
636 __ movq(rcx, result_register()); 636 __ movq(rcx, result_register());
637 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); 637 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex);
638 } 638 }
639 __ pop(rdx); 639 __ pop(rdx);
640 640
641 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 641 Handle<Code> ic(isolate()->builtins()->builtin(
642 Builtins::KeyedStoreIC_Initialize)); 642 Builtins::KeyedStoreIC_Initialize));
643 EmitCallIC(ic, RelocInfo::CODE_TARGET); 643 EmitCallIC(ic, RelocInfo::CODE_TARGET);
644 } 644 }
645 } 645 }
646 } 646 }
647 647
648 648
649 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 649 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
650 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 650 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
651 } 651 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 // space for nested functions that don't need literals cloning. 869 // space for nested functions that don't need literals cloning.
870 if (scope()->is_function_scope() && 870 if (scope()->is_function_scope() &&
871 info->num_literals() == 0 && 871 info->num_literals() == 0 &&
872 !pretenure) { 872 !pretenure) {
873 FastNewClosureStub stub; 873 FastNewClosureStub stub;
874 __ Push(info); 874 __ Push(info);
875 __ CallStub(&stub); 875 __ CallStub(&stub);
876 } else { 876 } else {
877 __ push(rsi); 877 __ push(rsi);
878 __ Push(info); 878 __ Push(info);
879 __ Push(pretenure ? FACTORY->true_value() : FACTORY->false_value()); 879 __ Push(pretenure
880 ? isolate()->factory()->true_value()
881 : isolate()->factory()->false_value());
880 __ CallRuntime(Runtime::kNewClosure, 3); 882 __ CallRuntime(Runtime::kNewClosure, 3);
881 } 883 }
882 context()->Plug(rax); 884 context()->Plug(rax);
883 } 885 }
884 886
885 887
886 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 888 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
887 Comment cmnt(masm_, "[ VariableProxy"); 889 Comment cmnt(masm_, "[ VariableProxy");
888 EmitVariableLoad(expr->var()); 890 EmitVariableLoad(expr->var());
889 } 891 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); 940 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX));
939 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); 941 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset));
940 __ jmp(&next); 942 __ jmp(&next);
941 __ bind(&fast); 943 __ bind(&fast);
942 } 944 }
943 945
944 // All extension objects were empty and it is safe to use a global 946 // All extension objects were empty and it is safe to use a global
945 // load IC call. 947 // load IC call.
946 __ movq(rax, GlobalObjectOperand()); 948 __ movq(rax, GlobalObjectOperand());
947 __ Move(rcx, slot->var()->name()); 949 __ Move(rcx, slot->var()->name());
948 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 950 Handle<Code> ic(isolate()->builtins()->builtin(
949 Builtins::LoadIC_Initialize)); 951 Builtins::LoadIC_Initialize));
950 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 952 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
951 ? RelocInfo::CODE_TARGET 953 ? RelocInfo::CODE_TARGET
952 : RelocInfo::CODE_TARGET_CONTEXT; 954 : RelocInfo::CODE_TARGET_CONTEXT;
953 EmitCallIC(ic, mode); 955 EmitCallIC(ic, mode);
954 } 956 }
955 957
956 958
957 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 959 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
958 Slot* slot, 960 Slot* slot,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 key_literal != NULL && 1021 key_literal != NULL &&
1020 obj_proxy->IsArguments() && 1022 obj_proxy->IsArguments() &&
1021 key_literal->handle()->IsSmi()) { 1023 key_literal->handle()->IsSmi()) {
1022 // Load arguments object if there are no eval-introduced 1024 // Load arguments object if there are no eval-introduced
1023 // variables. Then load the argument from the arguments 1025 // variables. Then load the argument from the arguments
1024 // object using keyed load. 1026 // object using keyed load.
1025 __ movq(rdx, 1027 __ movq(rdx,
1026 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1028 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1027 slow)); 1029 slow));
1028 __ Move(rax, key_literal->handle()); 1030 __ Move(rax, key_literal->handle());
1029 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1031 Handle<Code> ic(isolate()->builtins()->builtin(
1030 Builtins::KeyedLoadIC_Initialize)); 1032 Builtins::KeyedLoadIC_Initialize));
1031 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1033 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1032 __ jmp(done); 1034 __ jmp(done);
1033 } 1035 }
1034 } 1036 }
1035 } 1037 }
1036 } 1038 }
1037 } 1039 }
1038 1040
1039 1041
1040 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1042 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1041 // Four cases: non-this global variables, lookup slots, all other 1043 // Four cases: non-this global variables, lookup slots, all other
1042 // types of slots, and parameters that rewrite to explicit property 1044 // types of slots, and parameters that rewrite to explicit property
1043 // accesses on the arguments object. 1045 // accesses on the arguments object.
1044 Slot* slot = var->AsSlot(); 1046 Slot* slot = var->AsSlot();
1045 Property* property = var->AsProperty(); 1047 Property* property = var->AsProperty();
1046 1048
1047 if (var->is_global() && !var->is_this()) { 1049 if (var->is_global() && !var->is_this()) {
1048 Comment cmnt(masm_, "Global variable"); 1050 Comment cmnt(masm_, "Global variable");
1049 // Use inline caching. Variable name is passed in rcx and the global 1051 // Use inline caching. Variable name is passed in rcx and the global
1050 // object on the stack. 1052 // object on the stack.
1051 __ Move(rcx, var->name()); 1053 __ Move(rcx, var->name());
1052 __ movq(rax, GlobalObjectOperand()); 1054 __ movq(rax, GlobalObjectOperand());
1053 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1055 Handle<Code> ic(isolate()->builtins()->builtin(
1054 Builtins::LoadIC_Initialize)); 1056 Builtins::LoadIC_Initialize));
1055 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1057 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1056 context()->Plug(rax); 1058 context()->Plug(rax);
1057 1059
1058 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1060 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1059 Label done, slow; 1061 Label done, slow;
1060 1062
1061 // Generate code for loading from variables potentially shadowed 1063 // Generate code for loading from variables potentially shadowed
1062 // by eval-introduced variables. 1064 // by eval-introduced variables.
1063 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1065 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
(...skipping 10 matching lines...) Expand all
1074 } else if (slot != NULL) { 1076 } else if (slot != NULL) {
1075 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1077 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1076 ? "Context slot" 1078 ? "Context slot"
1077 : "Stack slot"); 1079 : "Stack slot");
1078 if (var->mode() == Variable::CONST) { 1080 if (var->mode() == Variable::CONST) {
1079 // Constants may be the hole value if they have not been initialized. 1081 // Constants may be the hole value if they have not been initialized.
1080 // Unhole them. 1082 // Unhole them.
1081 NearLabel done; 1083 NearLabel done;
1082 MemOperand slot_operand = EmitSlotSearch(slot, rax); 1084 MemOperand slot_operand = EmitSlotSearch(slot, rax);
1083 __ movq(rax, slot_operand); 1085 __ movq(rax, slot_operand);
1084 __ CompareRoot(rax, HEAP->kTheHoleValueRootIndex); 1086 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1085 __ j(not_equal, &done); 1087 __ j(not_equal, &done);
1086 __ LoadRoot(rax, HEAP->kUndefinedValueRootIndex); 1088 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1087 __ bind(&done); 1089 __ bind(&done);
1088 context()->Plug(rax); 1090 context()->Plug(rax);
1089 } else { 1091 } else {
1090 context()->Plug(slot); 1092 context()->Plug(slot);
1091 } 1093 }
1092 1094
1093 } else { 1095 } else {
1094 Comment cmnt(masm_, "Rewritten parameter"); 1096 Comment cmnt(masm_, "Rewritten parameter");
1095 ASSERT_NOT_NULL(property); 1097 ASSERT_NOT_NULL(property);
1096 // Rewritten parameter accesses are of the form "slot[literal]". 1098 // Rewritten parameter accesses are of the form "slot[literal]".
(...skipping 10 matching lines...) Expand all
1107 1109
1108 // Assert that the key is a smi. 1110 // Assert that the key is a smi.
1109 Literal* key_literal = property->key()->AsLiteral(); 1111 Literal* key_literal = property->key()->AsLiteral();
1110 ASSERT_NOT_NULL(key_literal); 1112 ASSERT_NOT_NULL(key_literal);
1111 ASSERT(key_literal->handle()->IsSmi()); 1113 ASSERT(key_literal->handle()->IsSmi());
1112 1114
1113 // Load the key. 1115 // Load the key.
1114 __ Move(rax, key_literal->handle()); 1116 __ Move(rax, key_literal->handle());
1115 1117
1116 // Do a keyed property load. 1118 // Do a keyed property load.
1117 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1119 Handle<Code> ic(isolate()->builtins()->builtin(
1118 Builtins::KeyedLoadIC_Initialize)); 1120 Builtins::KeyedLoadIC_Initialize));
1119 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1121 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1120 context()->Plug(rax); 1122 context()->Plug(rax);
1121 } 1123 }
1122 } 1124 }
1123 1125
1124 1126
1125 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1127 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1126 Comment cmnt(masm_, "[ RegExpLiteral"); 1128 Comment cmnt(masm_, "[ RegExpLiteral");
1127 Label materialized; 1129 Label materialized;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 UNREACHABLE(); 1215 UNREACHABLE();
1214 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1216 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1215 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1217 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1216 // Fall through. 1218 // Fall through.
1217 case ObjectLiteral::Property::COMPUTED: 1219 case ObjectLiteral::Property::COMPUTED:
1218 if (key->handle()->IsSymbol()) { 1220 if (key->handle()->IsSymbol()) {
1219 VisitForAccumulatorValue(value); 1221 VisitForAccumulatorValue(value);
1220 __ Move(rcx, key->handle()); 1222 __ Move(rcx, key->handle());
1221 __ movq(rdx, Operand(rsp, 0)); 1223 __ movq(rdx, Operand(rsp, 0));
1222 if (property->emit_store()) { 1224 if (property->emit_store()) {
1223 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1225 Handle<Code> ic(isolate()->builtins()->builtin(
1224 Builtins::StoreIC_Initialize)); 1226 Builtins::StoreIC_Initialize));
1225 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1227 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1226 } 1228 }
1227 break; 1229 break;
1228 } 1230 }
1229 // Fall through. 1231 // Fall through.
1230 case ObjectLiteral::Property::PROTOTYPE: 1232 case ObjectLiteral::Property::PROTOTYPE:
1231 __ push(Operand(rsp, 0)); // Duplicate receiver. 1233 __ push(Operand(rsp, 0)); // Duplicate receiver.
1232 VisitForStackValue(key); 1234 VisitForStackValue(key);
1233 VisitForStackValue(value); 1235 VisitForStackValue(value);
(...skipping 27 matching lines...) Expand all
1261 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1263 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1262 Comment cmnt(masm_, "[ ArrayLiteral"); 1264 Comment cmnt(masm_, "[ ArrayLiteral");
1263 1265
1264 ZoneList<Expression*>* subexprs = expr->values(); 1266 ZoneList<Expression*>* subexprs = expr->values();
1265 int length = subexprs->length(); 1267 int length = subexprs->length();
1266 1268
1267 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1269 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1268 __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); 1270 __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
1269 __ Push(Smi::FromInt(expr->literal_index())); 1271 __ Push(Smi::FromInt(expr->literal_index()));
1270 __ Push(expr->constant_elements()); 1272 __ Push(expr->constant_elements());
1271 if (expr->constant_elements()->map() == HEAP->fixed_cow_array_map()) { 1273 if (expr->constant_elements()->map() ==
1274 isolate()->heap()->fixed_cow_array_map()) {
1272 FastCloneShallowArrayStub stub( 1275 FastCloneShallowArrayStub stub(
1273 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); 1276 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
1274 __ CallStub(&stub); 1277 __ CallStub(&stub);
1275 __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1); 1278 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
1276 } else if (expr->depth() > 1) { 1279 } else if (expr->depth() > 1) {
1277 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1280 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
1278 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { 1281 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1279 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 1282 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1280 } else { 1283 } else {
1281 FastCloneShallowArrayStub stub( 1284 FastCloneShallowArrayStub stub(
1282 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); 1285 FastCloneShallowArrayStub::CLONE_ELEMENTS, length);
1283 __ CallStub(&stub); 1286 __ CallStub(&stub);
1284 } 1287 }
1285 1288
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 EmitKeyedPropertyAssignment(expr); 1430 EmitKeyedPropertyAssignment(expr);
1428 break; 1431 break;
1429 } 1432 }
1430 } 1433 }
1431 1434
1432 1435
1433 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1436 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1434 SetSourcePosition(prop->position()); 1437 SetSourcePosition(prop->position());
1435 Literal* key = prop->key()->AsLiteral(); 1438 Literal* key = prop->key()->AsLiteral();
1436 __ Move(rcx, key->handle()); 1439 __ Move(rcx, key->handle());
1437 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1440 Handle<Code> ic(isolate()->builtins()->builtin(
1438 Builtins::LoadIC_Initialize)); 1441 Builtins::LoadIC_Initialize));
1439 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1442 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1440 } 1443 }
1441 1444
1442 1445
1443 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1446 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1444 SetSourcePosition(prop->position()); 1447 SetSourcePosition(prop->position());
1445 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1448 Handle<Code> ic(isolate()->builtins()->builtin(
1446 Builtins::KeyedLoadIC_Initialize)); 1449 Builtins::KeyedLoadIC_Initialize));
1447 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1450 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1448 } 1451 }
1449 1452
1450 1453
1451 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1454 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1452 Token::Value op, 1455 Token::Value op,
1453 OverwriteMode mode, 1456 OverwriteMode mode,
1454 Expression* left, 1457 Expression* left,
1455 Expression* right, 1458 Expression* right,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 EffectContext context(this); 1557 EffectContext context(this);
1555 EmitVariableAssignment(var, Token::ASSIGN); 1558 EmitVariableAssignment(var, Token::ASSIGN);
1556 break; 1559 break;
1557 } 1560 }
1558 case NAMED_PROPERTY: { 1561 case NAMED_PROPERTY: {
1559 __ push(rax); // Preserve value. 1562 __ push(rax); // Preserve value.
1560 VisitForAccumulatorValue(prop->obj()); 1563 VisitForAccumulatorValue(prop->obj());
1561 __ movq(rdx, rax); 1564 __ movq(rdx, rax);
1562 __ pop(rax); // Restore value. 1565 __ pop(rax); // Restore value.
1563 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1566 __ Move(rcx, prop->key()->AsLiteral()->handle());
1564 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1567 Handle<Code> ic(isolate()->builtins()->builtin(
1565 Builtins::StoreIC_Initialize)); 1568 Builtins::StoreIC_Initialize));
1566 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1569 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1567 break; 1570 break;
1568 } 1571 }
1569 case KEYED_PROPERTY: { 1572 case KEYED_PROPERTY: {
1570 __ push(rax); // Preserve value. 1573 __ push(rax); // Preserve value.
1571 VisitForStackValue(prop->obj()); 1574 VisitForStackValue(prop->obj());
1572 VisitForAccumulatorValue(prop->key()); 1575 VisitForAccumulatorValue(prop->key());
1573 __ movq(rcx, rax); 1576 __ movq(rcx, rax);
1574 __ pop(rdx); 1577 __ pop(rdx);
1575 __ pop(rax); 1578 __ pop(rax);
1576 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1579 Handle<Code> ic(isolate()->builtins()->builtin(
1577 Builtins::KeyedStoreIC_Initialize)); 1580 Builtins::KeyedStoreIC_Initialize));
1578 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1581 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1579 break; 1582 break;
1580 } 1583 }
1581 } 1584 }
1582 } 1585 }
1583 1586
1584 1587
1585 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1588 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1586 Token::Value op) { 1589 Token::Value op) {
1587 // Left-hand sides that rewrite to explicit property accesses do not reach 1590 // Left-hand sides that rewrite to explicit property accesses do not reach
1588 // here. 1591 // here.
1589 ASSERT(var != NULL); 1592 ASSERT(var != NULL);
1590 ASSERT(var->is_global() || var->AsSlot() != NULL); 1593 ASSERT(var->is_global() || var->AsSlot() != NULL);
1591 1594
1592 if (var->is_global()) { 1595 if (var->is_global()) {
1593 ASSERT(!var->is_this()); 1596 ASSERT(!var->is_this());
1594 // Assignment to a global variable. Use inline caching for the 1597 // Assignment to a global variable. Use inline caching for the
1595 // assignment. Right-hand-side value is passed in rax, variable name in 1598 // assignment. Right-hand-side value is passed in rax, variable name in
1596 // rcx, and the global object on the stack. 1599 // rcx, and the global object on the stack.
1597 __ Move(rcx, var->name()); 1600 __ Move(rcx, var->name());
1598 __ movq(rdx, GlobalObjectOperand()); 1601 __ movq(rdx, GlobalObjectOperand());
1599 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1602 Handle<Code> ic(isolate()->builtins()->builtin(
1600 Builtins::StoreIC_Initialize)); 1603 Builtins::StoreIC_Initialize));
1601 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1604 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1602 1605
1603 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1606 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1604 // Perform the assignment for non-const variables and for initialization 1607 // Perform the assignment for non-const variables and for initialization
1605 // of const variables. Const assignments are simply skipped. 1608 // of const variables. Const assignments are simply skipped.
1606 Label done; 1609 Label done;
1607 Slot* slot = var->AsSlot(); 1610 Slot* slot = var->AsSlot();
1608 switch (slot->type()) { 1611 switch (slot->type()) {
1609 case Slot::PARAMETER: 1612 case Slot::PARAMETER:
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 } 1677 }
1675 1678
1676 // Record source code position before IC call. 1679 // Record source code position before IC call.
1677 SetSourcePosition(expr->position()); 1680 SetSourcePosition(expr->position());
1678 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1681 __ Move(rcx, prop->key()->AsLiteral()->handle());
1679 if (expr->ends_initialization_block()) { 1682 if (expr->ends_initialization_block()) {
1680 __ movq(rdx, Operand(rsp, 0)); 1683 __ movq(rdx, Operand(rsp, 0));
1681 } else { 1684 } else {
1682 __ pop(rdx); 1685 __ pop(rdx);
1683 } 1686 }
1684 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1687 Handle<Code> ic(isolate()->builtins()->builtin(
1685 Builtins::StoreIC_Initialize)); 1688 Builtins::StoreIC_Initialize));
1686 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1689 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1687 1690
1688 // If the assignment ends an initialization block, revert to fast case. 1691 // If the assignment ends an initialization block, revert to fast case.
1689 if (expr->ends_initialization_block()) { 1692 if (expr->ends_initialization_block()) {
1690 __ push(rax); // Result of assignment, saved even if not needed. 1693 __ push(rax); // Result of assignment, saved even if not needed.
1691 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1694 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1692 __ CallRuntime(Runtime::kToFastProperties, 1); 1695 __ CallRuntime(Runtime::kToFastProperties, 1);
1693 __ pop(rax); 1696 __ pop(rax);
1694 context()->DropAndPlug(1, rax); 1697 context()->DropAndPlug(1, rax);
(...skipping 18 matching lines...) Expand all
1713 } 1716 }
1714 1717
1715 __ pop(rcx); 1718 __ pop(rcx);
1716 if (expr->ends_initialization_block()) { 1719 if (expr->ends_initialization_block()) {
1717 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. 1720 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
1718 } else { 1721 } else {
1719 __ pop(rdx); 1722 __ pop(rdx);
1720 } 1723 }
1721 // Record source code position before IC call. 1724 // Record source code position before IC call.
1722 SetSourcePosition(expr->position()); 1725 SetSourcePosition(expr->position());
1723 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1726 Handle<Code> ic(isolate()->builtins()->builtin(
1724 Builtins::KeyedStoreIC_Initialize)); 1727 Builtins::KeyedStoreIC_Initialize));
1725 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1728 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1726 1729
1727 // If the assignment ends an initialization block, revert to fast case. 1730 // If the assignment ends an initialization block, revert to fast case.
1728 if (expr->ends_initialization_block()) { 1731 if (expr->ends_initialization_block()) {
1729 __ pop(rdx); 1732 __ pop(rdx);
1730 __ push(rax); // Result of assignment, saved even if not needed. 1733 __ push(rax); // Result of assignment, saved even if not needed.
1731 __ push(rdx); 1734 __ push(rdx);
1732 __ CallRuntime(Runtime::kToFastProperties, 1); 1735 __ CallRuntime(Runtime::kToFastProperties, 1);
1733 __ pop(rax); 1736 __ pop(rax);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 { PreservePositionScope scope(masm()->positions_recorder()); 1948 { PreservePositionScope scope(masm()->positions_recorder());
1946 VisitForStackValue(prop->obj()); 1949 VisitForStackValue(prop->obj());
1947 } 1950 }
1948 if (prop->is_synthetic()) { 1951 if (prop->is_synthetic()) {
1949 { PreservePositionScope scope(masm()->positions_recorder()); 1952 { PreservePositionScope scope(masm()->positions_recorder());
1950 VisitForAccumulatorValue(prop->key()); 1953 VisitForAccumulatorValue(prop->key());
1951 __ movq(rdx, Operand(rsp, 0)); 1954 __ movq(rdx, Operand(rsp, 0));
1952 } 1955 }
1953 // Record source code position for IC call. 1956 // Record source code position for IC call.
1954 SetSourcePosition(prop->position()); 1957 SetSourcePosition(prop->position());
1955 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1958 Handle<Code> ic(isolate()->builtins()->builtin(
1956 Builtins::KeyedLoadIC_Initialize)); 1959 Builtins::KeyedLoadIC_Initialize));
1957 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1960 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1958 // Pop receiver. 1961 // Pop receiver.
1959 __ pop(rbx); 1962 __ pop(rbx);
1960 // Push result (function). 1963 // Push result (function).
1961 __ push(rax); 1964 __ push(rax);
1962 // Push receiver object on stack. 1965 // Push receiver object on stack.
1963 __ movq(rcx, GlobalObjectOperand()); 1966 __ movq(rcx, GlobalObjectOperand());
1964 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 1967 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
1965 EmitCallWithStub(expr); 1968 EmitCallWithStub(expr);
1966 } else { 1969 } else {
1967 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 1970 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
1968 } 1971 }
1969 } 1972 }
1970 } else { 1973 } else {
1971 // Call to some other expression. If the expression is an anonymous 1974 // Call to some other expression. If the expression is an anonymous
1972 // function literal not called in a loop, mark it as one that should 1975 // function literal not called in a loop, mark it as one that should
1973 // also use the fast code generator. 1976 // also use the fast code generator.
1974 FunctionLiteral* lit = fun->AsFunctionLiteral(); 1977 FunctionLiteral* lit = fun->AsFunctionLiteral();
1975 if (lit != NULL && 1978 if (lit != NULL &&
1976 lit->name()->Equals(HEAP->empty_string()) && 1979 lit->name()->Equals(isolate()->heap()->empty_string()) &&
1977 loop_depth() == 0) { 1980 loop_depth() == 0) {
1978 lit->set_try_full_codegen(true); 1981 lit->set_try_full_codegen(true);
1979 } 1982 }
1980 { PreservePositionScope scope(masm()->positions_recorder()); 1983 { PreservePositionScope scope(masm()->positions_recorder());
1981 VisitForStackValue(fun); 1984 VisitForStackValue(fun);
1982 } 1985 }
1983 // Load global receiver object. 1986 // Load global receiver object.
1984 __ movq(rbx, GlobalObjectOperand()); 1987 __ movq(rbx, GlobalObjectOperand());
1985 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); 1988 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
1986 // Emit function call. 1989 // Emit function call.
(...skipping 21 matching lines...) Expand all
2008 } 2011 }
2009 2012
2010 // Call the construct call builtin that handles allocation and 2013 // Call the construct call builtin that handles allocation and
2011 // constructor invocation. 2014 // constructor invocation.
2012 SetSourcePosition(expr->position()); 2015 SetSourcePosition(expr->position());
2013 2016
2014 // Load function and argument count into rdi and rax. 2017 // Load function and argument count into rdi and rax.
2015 __ Set(rax, arg_count); 2018 __ Set(rax, arg_count);
2016 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); 2019 __ movq(rdi, Operand(rsp, arg_count * kPointerSize));
2017 2020
2018 Handle<Code> construct_builtin(Isolate::Current()->builtins()->builtin( 2021 Handle<Code> construct_builtin(isolate()->builtins()->builtin(
2019 Builtins::JSConstructCall)); 2022 Builtins::JSConstructCall));
2020 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2023 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2021 context()->Plug(rax); 2024 context()->Plug(rax);
2022 } 2025 }
2023 2026
2024 2027
2025 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2028 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2026 ASSERT(args->length() == 1); 2029 ASSERT(args->length() == 1);
2027 2030
2028 VisitForAccumulatorValue(args->at(0)); 2031 VisitForAccumulatorValue(args->at(0));
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 __ j(not_equal, &non_function_constructor); 2334 __ j(not_equal, &non_function_constructor);
2332 2335
2333 // rax now contains the constructor function. Grab the 2336 // rax now contains the constructor function. Grab the
2334 // instance class name from there. 2337 // instance class name from there.
2335 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); 2338 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
2336 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); 2339 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset));
2337 __ jmp(&done); 2340 __ jmp(&done);
2338 2341
2339 // Functions have class 'Function'. 2342 // Functions have class 'Function'.
2340 __ bind(&function); 2343 __ bind(&function);
2341 __ Move(rax, FACTORY->function_class_symbol()); 2344 __ Move(rax, isolate()->factory()->function_class_symbol());
2342 __ jmp(&done); 2345 __ jmp(&done);
2343 2346
2344 // Objects with a non-function constructor have class 'Object'. 2347 // Objects with a non-function constructor have class 'Object'.
2345 __ bind(&non_function_constructor); 2348 __ bind(&non_function_constructor);
2346 __ Move(rax, FACTORY->Object_symbol()); 2349 __ Move(rax, isolate()->factory()->Object_symbol());
2347 __ jmp(&done); 2350 __ jmp(&done);
2348 2351
2349 // Non-JS objects have class null. 2352 // Non-JS objects have class null.
2350 __ bind(&null); 2353 __ bind(&null);
2351 __ LoadRoot(rax, Heap::kNullValueRootIndex); 2354 __ LoadRoot(rax, Heap::kNullValueRootIndex);
2352 2355
2353 // All done. 2356 // All done.
2354 __ bind(&done); 2357 __ bind(&done);
2355 2358
2356 context()->Plug(rax); 2359 context()->Plug(rax);
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 } 2728 }
2726 2729
2727 2730
2728 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 2731 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
2729 ASSERT_EQ(2, args->length()); 2732 ASSERT_EQ(2, args->length());
2730 2733
2731 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 2734 ASSERT_NE(NULL, args->at(0)->AsLiteral());
2732 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 2735 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
2733 2736
2734 Handle<FixedArray> jsfunction_result_caches( 2737 Handle<FixedArray> jsfunction_result_caches(
2735 Isolate::Current()->global_context()->jsfunction_result_caches()); 2738 isolate()->global_context()->jsfunction_result_caches());
2736 if (jsfunction_result_caches->length() <= cache_id) { 2739 if (jsfunction_result_caches->length() <= cache_id) {
2737 __ Abort("Attempt to use undefined cache."); 2740 __ Abort("Attempt to use undefined cache.");
2738 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2741 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2739 context()->Plug(rax); 2742 context()->Plug(rax);
2740 return; 2743 return;
2741 } 2744 }
2742 2745
2743 VisitForAccumulatorValue(args->at(1)); 2746 VisitForAccumulatorValue(args->at(1));
2744 2747
2745 Register key = rax; 2748 Register key = rax;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); 2805 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset));
2803 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), 2806 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset),
2804 Immediate(JS_REGEXP_TYPE)); 2807 Immediate(JS_REGEXP_TYPE));
2805 __ j(not_equal, &fail); 2808 __ j(not_equal, &fail);
2806 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset)); 2809 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset));
2807 __ j(not_equal, &fail); 2810 __ j(not_equal, &fail);
2808 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 2811 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset));
2809 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 2812 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset));
2810 __ j(equal, &ok); 2813 __ j(equal, &ok);
2811 __ bind(&fail); 2814 __ bind(&fail);
2812 __ Move(rax, FACTORY->false_value()); 2815 __ Move(rax, isolate()->factory()->false_value());
2813 __ jmp(&done); 2816 __ jmp(&done);
2814 __ bind(&ok); 2817 __ bind(&ok);
2815 __ Move(rax, FACTORY->true_value()); 2818 __ Move(rax, isolate()->factory()->true_value());
2816 __ bind(&done); 2819 __ bind(&done);
2817 2820
2818 context()->Plug(rax); 2821 context()->Plug(rax);
2819 } 2822 }
2820 2823
2821 2824
2822 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 2825 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
2823 ASSERT(args->length() == 1); 2826 ASSERT(args->length() == 1);
2824 2827
2825 VisitForAccumulatorValue(args->at(0)); 2828 VisitForAccumulatorValue(args->at(0));
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 } 3156 }
3154 } else { 3157 } else {
3155 // Perform the assignment as if via '='. 3158 // Perform the assignment as if via '='.
3156 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3159 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3157 Token::ASSIGN); 3160 Token::ASSIGN);
3158 } 3161 }
3159 break; 3162 break;
3160 case NAMED_PROPERTY: { 3163 case NAMED_PROPERTY: {
3161 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3164 __ Move(rcx, prop->key()->AsLiteral()->handle());
3162 __ pop(rdx); 3165 __ pop(rdx);
3163 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 3166 Handle<Code> ic(isolate()->builtins()->builtin(
3164 Builtins::StoreIC_Initialize)); 3167 Builtins::StoreIC_Initialize));
3165 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3168 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3166 if (expr->is_postfix()) { 3169 if (expr->is_postfix()) {
3167 if (!context()->IsEffect()) { 3170 if (!context()->IsEffect()) {
3168 context()->PlugTOS(); 3171 context()->PlugTOS();
3169 } 3172 }
3170 } else { 3173 } else {
3171 context()->Plug(rax); 3174 context()->Plug(rax);
3172 } 3175 }
3173 break; 3176 break;
3174 } 3177 }
3175 case KEYED_PROPERTY: { 3178 case KEYED_PROPERTY: {
3176 __ pop(rcx); 3179 __ pop(rcx);
3177 __ pop(rdx); 3180 __ pop(rdx);
3178 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 3181 Handle<Code> ic(isolate()->builtins()->builtin(
3179 Builtins::KeyedStoreIC_Initialize)); 3182 Builtins::KeyedStoreIC_Initialize));
3180 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3183 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3181 if (expr->is_postfix()) { 3184 if (expr->is_postfix()) {
3182 if (!context()->IsEffect()) { 3185 if (!context()->IsEffect()) {
3183 context()->PlugTOS(); 3186 context()->PlugTOS();
3184 } 3187 }
3185 } else { 3188 } else {
3186 context()->Plug(rax); 3189 context()->Plug(rax);
3187 } 3190 }
3188 break; 3191 break;
3189 } 3192 }
3190 } 3193 }
3191 } 3194 }
3192 3195
3193 3196
3194 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3197 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3195 VariableProxy* proxy = expr->AsVariableProxy(); 3198 VariableProxy* proxy = expr->AsVariableProxy();
3196 ASSERT(!context()->IsEffect()); 3199 ASSERT(!context()->IsEffect());
3197 ASSERT(!context()->IsTest()); 3200 ASSERT(!context()->IsTest());
3198 3201
3199 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3202 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3200 Comment cmnt(masm_, "Global variable"); 3203 Comment cmnt(masm_, "Global variable");
3201 __ Move(rcx, proxy->name()); 3204 __ Move(rcx, proxy->name());
3202 __ movq(rax, GlobalObjectOperand()); 3205 __ movq(rax, GlobalObjectOperand());
3203 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 3206 Handle<Code> ic(isolate()->builtins()->builtin(
3204 Builtins::LoadIC_Initialize)); 3207 Builtins::LoadIC_Initialize));
3205 // Use a regular load, not a contextual load, to avoid a reference 3208 // Use a regular load, not a contextual load, to avoid a reference
3206 // error. 3209 // error.
3207 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3210 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3208 context()->Plug(rax); 3211 context()->Plug(rax);
3209 } else if (proxy != NULL && 3212 } else if (proxy != NULL &&
3210 proxy->var()->AsSlot() != NULL && 3213 proxy->var()->AsSlot() != NULL &&
3211 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3214 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3212 Label done, slow; 3215 Label done, slow;
3213 3216
(...skipping 30 matching lines...) Expand all
3244 Handle<Object> right_literal_value = right_literal->handle(); 3247 Handle<Object> right_literal_value = right_literal->handle();
3245 if (!right_literal_value->IsString()) return false; 3248 if (!right_literal_value->IsString()) return false;
3246 UnaryOperation* left_unary = left->AsUnaryOperation(); 3249 UnaryOperation* left_unary = left->AsUnaryOperation();
3247 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; 3250 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
3248 Handle<String> check = Handle<String>::cast(right_literal_value); 3251 Handle<String> check = Handle<String>::cast(right_literal_value);
3249 3252
3250 { AccumulatorValueContext context(this); 3253 { AccumulatorValueContext context(this);
3251 VisitForTypeofValue(left_unary->expression()); 3254 VisitForTypeofValue(left_unary->expression());
3252 } 3255 }
3253 3256
3254 if (check->Equals(HEAP->number_symbol())) { 3257 if (check->Equals(isolate()->heap()->number_symbol())) {
3255 Condition is_smi = masm_->CheckSmi(rax); 3258 Condition is_smi = masm_->CheckSmi(rax);
3256 __ j(is_smi, if_true); 3259 __ j(is_smi, if_true);
3257 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); 3260 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset));
3258 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); 3261 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex);
3259 Split(equal, if_true, if_false, fall_through); 3262 Split(equal, if_true, if_false, fall_through);
3260 } else if (check->Equals(HEAP->string_symbol())) { 3263 } else if (check->Equals(isolate()->heap()->string_symbol())) {
3261 Condition is_smi = masm_->CheckSmi(rax); 3264 Condition is_smi = masm_->CheckSmi(rax);
3262 __ j(is_smi, if_false); 3265 __ j(is_smi, if_false);
3263 // Check for undetectable objects => false. 3266 // Check for undetectable objects => false.
3264 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 3267 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
3265 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3268 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3266 Immediate(1 << Map::kIsUndetectable)); 3269 Immediate(1 << Map::kIsUndetectable));
3267 __ j(not_zero, if_false); 3270 __ j(not_zero, if_false);
3268 __ CmpInstanceType(rdx, FIRST_NONSTRING_TYPE); 3271 __ CmpInstanceType(rdx, FIRST_NONSTRING_TYPE);
3269 Split(below, if_true, if_false, fall_through); 3272 Split(below, if_true, if_false, fall_through);
3270 } else if (check->Equals(HEAP->boolean_symbol())) { 3273 } else if (check->Equals(isolate()->heap()->boolean_symbol())) {
3271 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 3274 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
3272 __ j(equal, if_true); 3275 __ j(equal, if_true);
3273 __ CompareRoot(rax, Heap::kFalseValueRootIndex); 3276 __ CompareRoot(rax, Heap::kFalseValueRootIndex);
3274 Split(equal, if_true, if_false, fall_through); 3277 Split(equal, if_true, if_false, fall_through);
3275 } else if (check->Equals(HEAP->undefined_symbol())) { 3278 } else if (check->Equals(isolate()->heap()->undefined_symbol())) {
3276 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 3279 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
3277 __ j(equal, if_true); 3280 __ j(equal, if_true);
3278 Condition is_smi = masm_->CheckSmi(rax); 3281 Condition is_smi = masm_->CheckSmi(rax);
3279 __ j(is_smi, if_false); 3282 __ j(is_smi, if_false);
3280 // Check for undetectable objects => true. 3283 // Check for undetectable objects => true.
3281 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 3284 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
3282 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3285 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3283 Immediate(1 << Map::kIsUndetectable)); 3286 Immediate(1 << Map::kIsUndetectable));
3284 Split(not_zero, if_true, if_false, fall_through); 3287 Split(not_zero, if_true, if_false, fall_through);
3285 } else if (check->Equals(HEAP->function_symbol())) { 3288 } else if (check->Equals(isolate()->heap()->function_symbol())) {
3286 Condition is_smi = masm_->CheckSmi(rax); 3289 Condition is_smi = masm_->CheckSmi(rax);
3287 __ j(is_smi, if_false); 3290 __ j(is_smi, if_false);
3288 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rdx); 3291 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rdx);
3289 __ j(equal, if_true); 3292 __ j(equal, if_true);
3290 // Regular expressions => 'function' (they are callable). 3293 // Regular expressions => 'function' (they are callable).
3291 __ CmpInstanceType(rdx, JS_REGEXP_TYPE); 3294 __ CmpInstanceType(rdx, JS_REGEXP_TYPE);
3292 Split(equal, if_true, if_false, fall_through); 3295 Split(equal, if_true, if_false, fall_through);
3293 } else if (check->Equals(HEAP->object_symbol())) { 3296 } else if (check->Equals(isolate()->heap()->object_symbol())) {
3294 Condition is_smi = masm_->CheckSmi(rax); 3297 Condition is_smi = masm_->CheckSmi(rax);
3295 __ j(is_smi, if_false); 3298 __ j(is_smi, if_false);
3296 __ CompareRoot(rax, Heap::kNullValueRootIndex); 3299 __ CompareRoot(rax, Heap::kNullValueRootIndex);
3297 __ j(equal, if_true); 3300 __ j(equal, if_true);
3298 // Regular expressions => 'function', not 'object'. 3301 // Regular expressions => 'function', not 'object'.
3299 __ CmpObjectType(rax, JS_REGEXP_TYPE, rdx); 3302 __ CmpObjectType(rax, JS_REGEXP_TYPE, rdx);
3300 __ j(equal, if_false); 3303 __ j(equal, if_false);
3301 // Check for undetectable objects => false. 3304 // Check for undetectable objects => false.
3302 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3305 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3303 Immediate(1 << Map::kIsUndetectable)); 3306 Immediate(1 << Map::kIsUndetectable));
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
3534 __ ret(0); 3537 __ ret(0);
3535 } 3538 }
3536 3539
3537 3540
3538 #undef __ 3541 #undef __
3539 3542
3540 3543
3541 } } // namespace v8::internal 3544 } } // namespace v8::internal
3542 3545
3543 #endif // V8_TARGET_ARCH_X64 3546 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698