| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |