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

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

Issue 1553703002: [runtime] TailCallRuntime and CallRuntime should use default argument counts (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-12-29_TailCallRuntime_default_result_size_1_1550923002
Patch Set: Created 4 years, 11 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 127 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
128 if (locals_count == 1) { 128 if (locals_count == 1) {
129 __ PushRoot(Heap::kUndefinedValueRootIndex); 129 __ PushRoot(Heap::kUndefinedValueRootIndex);
130 } else if (locals_count > 1) { 130 } else if (locals_count > 1) {
131 if (locals_count >= 128) { 131 if (locals_count >= 128) {
132 Label ok; 132 Label ok;
133 __ movp(rcx, rsp); 133 __ movp(rcx, rsp);
134 __ subp(rcx, Immediate(locals_count * kPointerSize)); 134 __ subp(rcx, Immediate(locals_count * kPointerSize));
135 __ CompareRoot(rcx, Heap::kRealStackLimitRootIndex); 135 __ CompareRoot(rcx, Heap::kRealStackLimitRootIndex);
136 __ j(above_equal, &ok, Label::kNear); 136 __ j(above_equal, &ok, Label::kNear);
137 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 137 __ CallRuntime(Runtime::kThrowStackOverflow);
138 __ bind(&ok); 138 __ bind(&ok);
139 } 139 }
140 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 140 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
141 const int kMaxPushes = 32; 141 const int kMaxPushes = 32;
142 if (locals_count >= kMaxPushes) { 142 if (locals_count >= kMaxPushes) {
143 int loop_iterations = locals_count / kMaxPushes; 143 int loop_iterations = locals_count / kMaxPushes;
144 __ movp(rcx, Immediate(loop_iterations)); 144 __ movp(rcx, Immediate(loop_iterations));
145 Label loop_header; 145 Label loop_header;
146 __ bind(&loop_header); 146 __ bind(&loop_header);
147 // Do pushes. 147 // Do pushes.
(...skipping 16 matching lines...) Expand all
164 164
165 // Possibly allocate a local context. 165 // Possibly allocate a local context.
166 if (info->scope()->num_heap_slots() > 0) { 166 if (info->scope()->num_heap_slots() > 0) {
167 Comment cmnt(masm_, "[ Allocate context"); 167 Comment cmnt(masm_, "[ Allocate context");
168 bool need_write_barrier = true; 168 bool need_write_barrier = true;
169 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 169 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
170 // Argument to NewContext is the function, which is still in rdi. 170 // Argument to NewContext is the function, which is still in rdi.
171 if (info->scope()->is_script_scope()) { 171 if (info->scope()->is_script_scope()) {
172 __ Push(rdi); 172 __ Push(rdi);
173 __ Push(info->scope()->GetScopeInfo(info->isolate())); 173 __ Push(info->scope()->GetScopeInfo(info->isolate()));
174 __ CallRuntime(Runtime::kNewScriptContext, 2); 174 __ CallRuntime(Runtime::kNewScriptContext);
175 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 175 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
176 // The new target value is not used, clobbering is safe. 176 // The new target value is not used, clobbering is safe.
177 DCHECK_NULL(info->scope()->new_target_var()); 177 DCHECK_NULL(info->scope()->new_target_var());
178 } else { 178 } else {
179 if (info->scope()->new_target_var() != nullptr) { 179 if (info->scope()->new_target_var() != nullptr) {
180 __ Push(rdx); // Preserve new target. 180 __ Push(rdx); // Preserve new target.
181 } 181 }
182 if (slots <= FastNewContextStub::kMaximumSlots) { 182 if (slots <= FastNewContextStub::kMaximumSlots) {
183 FastNewContextStub stub(isolate(), slots); 183 FastNewContextStub stub(isolate(), slots);
184 __ CallStub(&stub); 184 __ CallStub(&stub);
185 // Result of FastNewContextStub is always in new space. 185 // Result of FastNewContextStub is always in new space.
186 need_write_barrier = false; 186 need_write_barrier = false;
187 } else { 187 } else {
188 __ Push(rdi); 188 __ Push(rdi);
189 __ CallRuntime(Runtime::kNewFunctionContext, 1); 189 __ CallRuntime(Runtime::kNewFunctionContext);
190 } 190 }
191 if (info->scope()->new_target_var() != nullptr) { 191 if (info->scope()->new_target_var() != nullptr) {
192 __ Pop(rdx); // Restore new target. 192 __ Pop(rdx); // Restore new target.
193 } 193 }
194 } 194 }
195 function_in_register = false; 195 function_in_register = false;
196 // Context is returned in rax. It replaces the context passed to us. 196 // Context is returned in rax. It replaces the context passed to us.
197 // It's saved in the stack and kept live in rsi. 197 // It's saved in the stack and kept live in rsi.
198 __ movp(rsi, rax); 198 __ movp(rsi, rax);
199 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); 199 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters(); 297 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
298 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( 298 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
299 is_unmapped, literal()->has_duplicate_parameters()); 299 is_unmapped, literal()->has_duplicate_parameters());
300 ArgumentsAccessStub stub(isolate(), type); 300 ArgumentsAccessStub stub(isolate(), type);
301 __ CallStub(&stub); 301 __ CallStub(&stub);
302 302
303 SetVar(arguments, rax, rbx, rdx); 303 SetVar(arguments, rax, rbx, rdx);
304 } 304 }
305 305
306 if (FLAG_trace) { 306 if (FLAG_trace) {
307 __ CallRuntime(Runtime::kTraceEnter, 0); 307 __ CallRuntime(Runtime::kTraceEnter);
308 } 308 }
309 309
310 // Visit the declarations and body unless there is an illegal 310 // Visit the declarations and body unless there is an illegal
311 // redeclaration. 311 // redeclaration.
312 if (scope()->HasIllegalRedeclaration()) { 312 if (scope()->HasIllegalRedeclaration()) {
313 Comment cmnt(masm_, "[ Declarations"); 313 Comment cmnt(masm_, "[ Declarations");
314 VisitForEffect(scope()->GetIllegalRedeclaration()); 314 VisitForEffect(scope()->GetIllegalRedeclaration());
315 315
316 } else { 316 } else {
317 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 317 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 407
408 408
409 void FullCodeGenerator::EmitReturnSequence() { 409 void FullCodeGenerator::EmitReturnSequence() {
410 Comment cmnt(masm_, "[ Return sequence"); 410 Comment cmnt(masm_, "[ Return sequence");
411 if (return_label_.is_bound()) { 411 if (return_label_.is_bound()) {
412 __ jmp(&return_label_); 412 __ jmp(&return_label_);
413 } else { 413 } else {
414 __ bind(&return_label_); 414 __ bind(&return_label_);
415 if (FLAG_trace) { 415 if (FLAG_trace) {
416 __ Push(rax); 416 __ Push(rax);
417 __ CallRuntime(Runtime::kTraceExit, 1); 417 __ CallRuntime(Runtime::kTraceExit);
418 } 418 }
419 // Pretend that the exit is a backwards jump to the entry. 419 // Pretend that the exit is a backwards jump to the entry.
420 int weight = 1; 420 int weight = 1;
421 if (info_->ShouldSelfOptimize()) { 421 if (info_->ShouldSelfOptimize()) {
422 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 422 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
423 } else { 423 } else {
424 int distance = masm_->pc_offset(); 424 int distance = masm_->pc_offset();
425 weight = Min(kMaxBackEdgeWeight, 425 weight = Min(kMaxBackEdgeWeight,
426 Max(1, distance / kCodeSizeMultiplier)); 426 Max(1, distance / kCodeSizeMultiplier));
427 } 427 }
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 // Push initial value, if any. 801 // Push initial value, if any.
802 // Note: For variables we must not push an initial value (such as 802 // Note: For variables we must not push an initial value (such as
803 // 'undefined') because we may have a (legal) redeclaration and we 803 // 'undefined') because we may have a (legal) redeclaration and we
804 // must not destroy the current value. 804 // must not destroy the current value.
805 if (hole_init) { 805 if (hole_init) {
806 __ PushRoot(Heap::kTheHoleValueRootIndex); 806 __ PushRoot(Heap::kTheHoleValueRootIndex);
807 } else { 807 } else {
808 __ Push(Smi::FromInt(0)); // Indicates no initial value. 808 __ Push(Smi::FromInt(0)); // Indicates no initial value.
809 } 809 }
810 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 810 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
811 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 811 __ CallRuntime(Runtime::kDeclareLookupSlot);
812 break; 812 break;
813 } 813 }
814 } 814 }
815 } 815 }
816 816
817 817
818 void FullCodeGenerator::VisitFunctionDeclaration( 818 void FullCodeGenerator::VisitFunctionDeclaration(
819 FunctionDeclaration* declaration) { 819 FunctionDeclaration* declaration) {
820 VariableProxy* proxy = declaration->proxy(); 820 VariableProxy* proxy = declaration->proxy();
821 Variable* variable = proxy->var(); 821 Variable* variable = proxy->var();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 OMIT_SMI_CHECK); 855 OMIT_SMI_CHECK);
856 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 856 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
857 break; 857 break;
858 } 858 }
859 859
860 case VariableLocation::LOOKUP: { 860 case VariableLocation::LOOKUP: {
861 Comment cmnt(masm_, "[ FunctionDeclaration"); 861 Comment cmnt(masm_, "[ FunctionDeclaration");
862 __ Push(variable->name()); 862 __ Push(variable->name());
863 VisitForStackValue(declaration->fun()); 863 VisitForStackValue(declaration->fun());
864 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 864 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
865 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 865 __ CallRuntime(Runtime::kDeclareLookupSlot);
866 break; 866 break;
867 } 867 }
868 } 868 }
869 } 869 }
870 870
871 871
872 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 872 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
873 // Call the runtime to declare the globals. 873 // Call the runtime to declare the globals.
874 __ Push(pairs); 874 __ Push(pairs);
875 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 875 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
876 __ CallRuntime(Runtime::kDeclareGlobals, 2); 876 __ CallRuntime(Runtime::kDeclareGlobals);
877 // Return value is ignored. 877 // Return value is ignored.
878 } 878 }
879 879
880 880
881 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 881 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
882 // Call the runtime to declare the modules. 882 // Call the runtime to declare the modules.
883 __ Push(descriptions); 883 __ Push(descriptions);
884 __ CallRuntime(Runtime::kDeclareModules, 1); 884 __ CallRuntime(Runtime::kDeclareModules);
885 // Return value is ignored. 885 // Return value is ignored.
886 } 886 }
887 887
888 888
889 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 889 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
890 Comment cmnt(masm_, "[ SwitchStatement"); 890 Comment cmnt(masm_, "[ SwitchStatement");
891 Breakable nested_statement(this, stmt); 891 Breakable nested_statement(this, stmt);
892 SetStatementPosition(stmt); 892 SetStatementPosition(stmt);
893 893
894 // Keep the switch value on the stack until a case matches. 894 // Keep the switch value on the stack until a case matches.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 1028
1029 // The enum cache is valid. Load the map of the object being 1029 // The enum cache is valid. Load the map of the object being
1030 // iterated over and use the cache for the iteration. 1030 // iterated over and use the cache for the iteration.
1031 Label use_cache; 1031 Label use_cache;
1032 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); 1032 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset));
1033 __ jmp(&use_cache, Label::kNear); 1033 __ jmp(&use_cache, Label::kNear);
1034 1034
1035 // Get the set of properties to enumerate. 1035 // Get the set of properties to enumerate.
1036 __ bind(&call_runtime); 1036 __ bind(&call_runtime);
1037 __ Push(rax); // Duplicate the enumerable object on the stack. 1037 __ Push(rax); // Duplicate the enumerable object on the stack.
1038 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1038 __ CallRuntime(Runtime::kGetPropertyNamesFast);
1039 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1039 PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1040 1040
1041 // If we got a map from the runtime call, we can do a fast 1041 // If we got a map from the runtime call, we can do a fast
1042 // modification check. Otherwise, we got a fixed array, and we have 1042 // modification check. Otherwise, we got a fixed array, and we have
1043 // to do a slow check. 1043 // to do a slow check.
1044 Label fixed_array; 1044 Label fixed_array;
1045 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 1045 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
1046 Heap::kMetaMapRootIndex); 1046 Heap::kMetaMapRootIndex);
1047 __ j(not_equal, &fixed_array); 1047 __ j(not_equal, &fixed_array);
1048 1048
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 Label update_each; 1110 Label update_each;
1111 __ movp(rcx, Operand(rsp, 4 * kPointerSize)); 1111 __ movp(rcx, Operand(rsp, 4 * kPointerSize));
1112 __ cmpp(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); 1112 __ cmpp(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
1113 __ j(equal, &update_each, Label::kNear); 1113 __ j(equal, &update_each, Label::kNear);
1114 1114
1115 // Convert the entry to a string or null if it isn't a property 1115 // Convert the entry to a string or null if it isn't a property
1116 // anymore. If the property has been removed while iterating, we 1116 // anymore. If the property has been removed while iterating, we
1117 // just skip it. 1117 // just skip it.
1118 __ Push(rcx); // Enumerable. 1118 __ Push(rcx); // Enumerable.
1119 __ Push(rbx); // Current entry. 1119 __ Push(rbx); // Current entry.
1120 __ CallRuntime(Runtime::kForInFilter, 2); 1120 __ CallRuntime(Runtime::kForInFilter);
1121 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1121 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1122 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 1122 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
1123 __ j(equal, loop_statement.continue_label()); 1123 __ j(equal, loop_statement.continue_label());
1124 __ movp(rbx, rax); 1124 __ movp(rbx, rax);
1125 1125
1126 // Update the 'each' property or variable from the possibly filtered 1126 // Update the 'each' property or variable from the possibly filtered
1127 // entry in register rbx. 1127 // entry in register rbx.
1128 __ bind(&update_each); 1128 __ bind(&update_each);
1129 __ movp(result_register(), rbx); 1129 __ movp(result_register(), rbx);
1130 // Perform the assignment as if via '='. 1130 // Perform the assignment as if via '='.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 if (!FLAG_always_opt && 1168 if (!FLAG_always_opt &&
1169 !FLAG_prepare_always_opt && 1169 !FLAG_prepare_always_opt &&
1170 !pretenure && 1170 !pretenure &&
1171 scope()->is_function_scope() && 1171 scope()->is_function_scope() &&
1172 info->num_literals() == 0) { 1172 info->num_literals() == 0) {
1173 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); 1173 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1174 __ Move(rbx, info); 1174 __ Move(rbx, info);
1175 __ CallStub(&stub); 1175 __ CallStub(&stub);
1176 } else { 1176 } else {
1177 __ Push(info); 1177 __ Push(info);
1178 __ CallRuntime( 1178 __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
1179 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); 1179 : Runtime::kNewClosure);
1180 } 1180 }
1181 context()->Plug(rax); 1181 context()->Plug(rax);
1182 } 1182 }
1183 1183
1184 1184
1185 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1185 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1186 FeedbackVectorSlot slot) { 1186 FeedbackVectorSlot slot) {
1187 DCHECK(NeedsHomeObject(initializer)); 1187 DCHECK(NeedsHomeObject(initializer));
1188 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1188 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1189 __ Move(StoreDescriptor::NameRegister(), 1189 __ Move(StoreDescriptor::NameRegister(),
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 Variable* local = var->local_if_not_shadowed(); 1308 Variable* local = var->local_if_not_shadowed();
1309 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow)); 1309 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow));
1310 if (local->mode() == LET || local->mode() == CONST || 1310 if (local->mode() == LET || local->mode() == CONST ||
1311 local->mode() == CONST_LEGACY) { 1311 local->mode() == CONST_LEGACY) {
1312 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1312 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1313 __ j(not_equal, done); 1313 __ j(not_equal, done);
1314 if (local->mode() == CONST_LEGACY) { 1314 if (local->mode() == CONST_LEGACY) {
1315 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1315 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1316 } else { // LET || CONST 1316 } else { // LET || CONST
1317 __ Push(var->name()); 1317 __ Push(var->name());
1318 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1318 __ CallRuntime(Runtime::kThrowReferenceError);
1319 } 1319 }
1320 } 1320 }
1321 __ jmp(done); 1321 __ jmp(done);
1322 } 1322 }
1323 } 1323 }
1324 1324
1325 1325
1326 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1326 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1327 TypeofMode typeof_mode) { 1327 TypeofMode typeof_mode) {
1328 Variable* var = proxy->var(); 1328 Variable* var = proxy->var();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 if (NeedsHoleCheckForLoad(proxy)) { 1363 if (NeedsHoleCheckForLoad(proxy)) {
1364 // Let and const need a read barrier. 1364 // Let and const need a read barrier.
1365 Label done; 1365 Label done;
1366 GetVar(rax, var); 1366 GetVar(rax, var);
1367 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1367 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1368 __ j(not_equal, &done, Label::kNear); 1368 __ j(not_equal, &done, Label::kNear);
1369 if (var->mode() == LET || var->mode() == CONST) { 1369 if (var->mode() == LET || var->mode() == CONST) {
1370 // Throw a reference error when using an uninitialized let/const 1370 // Throw a reference error when using an uninitialized let/const
1371 // binding in harmony mode. 1371 // binding in harmony mode.
1372 __ Push(var->name()); 1372 __ Push(var->name());
1373 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1373 __ CallRuntime(Runtime::kThrowReferenceError);
1374 } else { 1374 } else {
1375 // Uninitialized legacy const bindings are unholed. 1375 // Uninitialized legacy const bindings are unholed.
1376 DCHECK(var->mode() == CONST_LEGACY); 1376 DCHECK(var->mode() == CONST_LEGACY);
1377 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1377 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1378 } 1378 }
1379 __ bind(&done); 1379 __ bind(&done);
1380 context()->Plug(rax); 1380 context()->Plug(rax);
1381 break; 1381 break;
1382 } 1382 }
1383 context()->Plug(var); 1383 context()->Plug(var);
1384 break; 1384 break;
1385 } 1385 }
1386 1386
1387 case VariableLocation::LOOKUP: { 1387 case VariableLocation::LOOKUP: {
1388 Comment cmnt(masm_, "[ Lookup slot"); 1388 Comment cmnt(masm_, "[ Lookup slot");
1389 Label done, slow; 1389 Label done, slow;
1390 // Generate code for loading from variables potentially shadowed 1390 // Generate code for loading from variables potentially shadowed
1391 // by eval-introduced variables. 1391 // by eval-introduced variables.
1392 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done); 1392 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1393 __ bind(&slow); 1393 __ bind(&slow);
1394 __ Push(rsi); // Context. 1394 __ Push(rsi); // Context.
1395 __ Push(var->name()); 1395 __ Push(var->name());
1396 Runtime::FunctionId function_id = 1396 Runtime::FunctionId function_id =
1397 typeof_mode == NOT_INSIDE_TYPEOF 1397 typeof_mode == NOT_INSIDE_TYPEOF
1398 ? Runtime::kLoadLookupSlot 1398 ? Runtime::kLoadLookupSlot
1399 : Runtime::kLoadLookupSlotNoReferenceError; 1399 : Runtime::kLoadLookupSlotNoReferenceError;
1400 __ CallRuntime(function_id, 2); 1400 __ CallRuntime(function_id);
1401 __ bind(&done); 1401 __ bind(&done);
1402 context()->Plug(rax); 1402 context()->Plug(rax);
1403 break; 1403 break;
1404 } 1404 }
1405 } 1405 }
1406 } 1406 }
1407 1407
1408 1408
1409 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1409 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1410 Comment cmnt(masm_, "[ RegExpLiteral"); 1410 Comment cmnt(masm_, "[ RegExpLiteral");
(...skipping 26 matching lines...) Expand all
1437 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1437 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1438 Comment cmnt(masm_, "[ ObjectLiteral"); 1438 Comment cmnt(masm_, "[ ObjectLiteral");
1439 1439
1440 Handle<FixedArray> constant_properties = expr->constant_properties(); 1440 Handle<FixedArray> constant_properties = expr->constant_properties();
1441 int flags = expr->ComputeFlags(); 1441 int flags = expr->ComputeFlags();
1442 if (MustCreateObjectLiteralWithRuntime(expr)) { 1442 if (MustCreateObjectLiteralWithRuntime(expr)) {
1443 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1443 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1444 __ Push(Smi::FromInt(expr->literal_index())); 1444 __ Push(Smi::FromInt(expr->literal_index()));
1445 __ Push(constant_properties); 1445 __ Push(constant_properties);
1446 __ Push(Smi::FromInt(flags)); 1446 __ Push(Smi::FromInt(flags));
1447 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1447 __ CallRuntime(Runtime::kCreateObjectLiteral);
1448 } else { 1448 } else {
1449 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1449 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1450 __ Move(rbx, Smi::FromInt(expr->literal_index())); 1450 __ Move(rbx, Smi::FromInt(expr->literal_index()));
1451 __ Move(rcx, constant_properties); 1451 __ Move(rcx, constant_properties);
1452 __ Move(rdx, Smi::FromInt(flags)); 1452 __ Move(rdx, Smi::FromInt(flags));
1453 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1453 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1454 __ CallStub(&stub); 1454 __ CallStub(&stub);
1455 } 1455 }
1456 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1456 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1457 1457
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 break; 1500 break;
1501 } 1501 }
1502 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1502 __ Push(Operand(rsp, 0)); // Duplicate receiver.
1503 VisitForStackValue(key); 1503 VisitForStackValue(key);
1504 VisitForStackValue(value); 1504 VisitForStackValue(value);
1505 if (property->emit_store()) { 1505 if (property->emit_store()) {
1506 if (NeedsHomeObject(value)) { 1506 if (NeedsHomeObject(value)) {
1507 EmitSetHomeObject(value, 2, property->GetSlot()); 1507 EmitSetHomeObject(value, 2, property->GetSlot());
1508 } 1508 }
1509 __ Push(Smi::FromInt(SLOPPY)); // Language mode 1509 __ Push(Smi::FromInt(SLOPPY)); // Language mode
1510 __ CallRuntime(Runtime::kSetProperty, 4); 1510 __ CallRuntime(Runtime::kSetProperty);
1511 } else { 1511 } else {
1512 __ Drop(3); 1512 __ Drop(3);
1513 } 1513 }
1514 break; 1514 break;
1515 case ObjectLiteral::Property::PROTOTYPE: 1515 case ObjectLiteral::Property::PROTOTYPE:
1516 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1516 __ Push(Operand(rsp, 0)); // Duplicate receiver.
1517 VisitForStackValue(value); 1517 VisitForStackValue(value);
1518 DCHECK(property->emit_store()); 1518 DCHECK(property->emit_store());
1519 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1519 __ CallRuntime(Runtime::kInternalSetPrototype);
1520 break; 1520 break;
1521 case ObjectLiteral::Property::GETTER: 1521 case ObjectLiteral::Property::GETTER:
1522 if (property->emit_store()) { 1522 if (property->emit_store()) {
1523 accessor_table.lookup(key)->second->getter = property; 1523 accessor_table.lookup(key)->second->getter = property;
1524 } 1524 }
1525 break; 1525 break;
1526 case ObjectLiteral::Property::SETTER: 1526 case ObjectLiteral::Property::SETTER:
1527 if (property->emit_store()) { 1527 if (property->emit_store()) {
1528 accessor_table.lookup(key)->second->setter = property; 1528 accessor_table.lookup(key)->second->setter = property;
1529 } 1529 }
1530 break; 1530 break;
1531 } 1531 }
1532 } 1532 }
1533 1533
1534 // Emit code to define accessors, using only a single call to the runtime for 1534 // Emit code to define accessors, using only a single call to the runtime for
1535 // each pair of corresponding getters and setters. 1535 // each pair of corresponding getters and setters.
1536 for (AccessorTable::Iterator it = accessor_table.begin(); 1536 for (AccessorTable::Iterator it = accessor_table.begin();
1537 it != accessor_table.end(); 1537 it != accessor_table.end();
1538 ++it) { 1538 ++it) {
1539 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1539 __ Push(Operand(rsp, 0)); // Duplicate receiver.
1540 VisitForStackValue(it->first); 1540 VisitForStackValue(it->first);
1541 EmitAccessor(it->second->getter); 1541 EmitAccessor(it->second->getter);
1542 EmitAccessor(it->second->setter); 1542 EmitAccessor(it->second->setter);
1543 __ Push(Smi::FromInt(NONE)); 1543 __ Push(Smi::FromInt(NONE));
1544 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1544 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
1545 } 1545 }
1546 1546
1547 // Object literals have two parts. The "static" part on the left contains no 1547 // Object literals have two parts. The "static" part on the left contains no
1548 // computed property names, and so we can compute its map ahead of time; see 1548 // computed property names, and so we can compute its map ahead of time; see
1549 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1549 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1550 // starts with the first computed property name, and continues with all 1550 // starts with the first computed property name, and continues with all
1551 // properties to its right. All the code from above initializes the static 1551 // properties to its right. All the code from above initializes the static
1552 // component of the object literal, and arranges for the map of the result to 1552 // component of the object literal, and arranges for the map of the result to
1553 // reflect the static order in which the keys appear. For the dynamic 1553 // reflect the static order in which the keys appear. For the dynamic
1554 // properties, we compile them into a series of "SetOwnProperty" runtime 1554 // properties, we compile them into a series of "SetOwnProperty" runtime
1555 // calls. This will preserve insertion order. 1555 // calls. This will preserve insertion order.
1556 for (; property_index < expr->properties()->length(); property_index++) { 1556 for (; property_index < expr->properties()->length(); property_index++) {
1557 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1557 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1558 1558
1559 Expression* value = property->value(); 1559 Expression* value = property->value();
1560 if (!result_saved) { 1560 if (!result_saved) {
1561 __ Push(rax); // Save result on the stack 1561 __ Push(rax); // Save result on the stack
1562 result_saved = true; 1562 result_saved = true;
1563 } 1563 }
1564 1564
1565 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1565 __ Push(Operand(rsp, 0)); // Duplicate receiver.
1566 1566
1567 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1567 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1568 DCHECK(!property->is_computed_name()); 1568 DCHECK(!property->is_computed_name());
1569 VisitForStackValue(value); 1569 VisitForStackValue(value);
1570 DCHECK(property->emit_store()); 1570 DCHECK(property->emit_store());
1571 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1571 __ CallRuntime(Runtime::kInternalSetPrototype);
1572 } else { 1572 } else {
1573 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1573 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1574 VisitForStackValue(value); 1574 VisitForStackValue(value);
1575 if (NeedsHomeObject(value)) { 1575 if (NeedsHomeObject(value)) {
1576 EmitSetHomeObject(value, 2, property->GetSlot()); 1576 EmitSetHomeObject(value, 2, property->GetSlot());
1577 } 1577 }
1578 1578
1579 switch (property->kind()) { 1579 switch (property->kind()) {
1580 case ObjectLiteral::Property::CONSTANT: 1580 case ObjectLiteral::Property::CONSTANT:
1581 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1581 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1582 case ObjectLiteral::Property::COMPUTED: 1582 case ObjectLiteral::Property::COMPUTED:
1583 if (property->emit_store()) { 1583 if (property->emit_store()) {
1584 __ Push(Smi::FromInt(NONE)); 1584 __ Push(Smi::FromInt(NONE));
1585 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1585 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked);
1586 } else { 1586 } else {
1587 __ Drop(3); 1587 __ Drop(3);
1588 } 1588 }
1589 break; 1589 break;
1590 1590
1591 case ObjectLiteral::Property::PROTOTYPE: 1591 case ObjectLiteral::Property::PROTOTYPE:
1592 UNREACHABLE(); 1592 UNREACHABLE();
1593 break; 1593 break;
1594 1594
1595 case ObjectLiteral::Property::GETTER: 1595 case ObjectLiteral::Property::GETTER:
1596 __ Push(Smi::FromInt(NONE)); 1596 __ Push(Smi::FromInt(NONE));
1597 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 1597 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
1598 break; 1598 break;
1599 1599
1600 case ObjectLiteral::Property::SETTER: 1600 case ObjectLiteral::Property::SETTER:
1601 __ Push(Smi::FromInt(NONE)); 1601 __ Push(Smi::FromInt(NONE));
1602 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 1602 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
1603 break; 1603 break;
1604 } 1604 }
1605 } 1605 }
1606 } 1606 }
1607 1607
1608 if (expr->has_function()) { 1608 if (expr->has_function()) {
1609 DCHECK(result_saved); 1609 DCHECK(result_saved);
1610 __ Push(Operand(rsp, 0)); 1610 __ Push(Operand(rsp, 0));
1611 __ CallRuntime(Runtime::kToFastProperties, 1); 1611 __ CallRuntime(Runtime::kToFastProperties);
1612 } 1612 }
1613 1613
1614 if (result_saved) { 1614 if (result_saved) {
1615 context()->PlugTOS(); 1615 context()->PlugTOS();
1616 } else { 1616 } else {
1617 context()->Plug(rax); 1617 context()->Plug(rax);
1618 } 1618 }
1619 } 1619 }
1620 1620
1621 1621
1622 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1622 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1623 Comment cmnt(masm_, "[ ArrayLiteral"); 1623 Comment cmnt(masm_, "[ ArrayLiteral");
1624 1624
1625 Handle<FixedArray> constant_elements = expr->constant_elements(); 1625 Handle<FixedArray> constant_elements = expr->constant_elements();
1626 bool has_constant_fast_elements = 1626 bool has_constant_fast_elements =
1627 IsFastObjectElementsKind(expr->constant_elements_kind()); 1627 IsFastObjectElementsKind(expr->constant_elements_kind());
1628 1628
1629 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE; 1629 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
1630 if (has_constant_fast_elements && !FLAG_allocation_site_pretenuring) { 1630 if (has_constant_fast_elements && !FLAG_allocation_site_pretenuring) {
1631 // If the only customer of allocation sites is transitioning, then 1631 // If the only customer of allocation sites is transitioning, then
1632 // we can turn it off if we don't have anywhere else to transition to. 1632 // we can turn it off if we don't have anywhere else to transition to.
1633 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1633 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1634 } 1634 }
1635 1635
1636 if (MustCreateArrayLiteralWithRuntime(expr)) { 1636 if (MustCreateArrayLiteralWithRuntime(expr)) {
1637 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1637 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1638 __ Push(Smi::FromInt(expr->literal_index())); 1638 __ Push(Smi::FromInt(expr->literal_index()));
1639 __ Push(constant_elements); 1639 __ Push(constant_elements);
1640 __ Push(Smi::FromInt(expr->ComputeFlags())); 1640 __ Push(Smi::FromInt(expr->ComputeFlags()));
1641 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1641 __ CallRuntime(Runtime::kCreateArrayLiteral);
1642 } else { 1642 } else {
1643 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1643 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1644 __ Move(rbx, Smi::FromInt(expr->literal_index())); 1644 __ Move(rbx, Smi::FromInt(expr->literal_index()));
1645 __ Move(rcx, constant_elements); 1645 __ Move(rcx, constant_elements);
1646 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1646 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1647 __ CallStub(&stub); 1647 __ CallStub(&stub);
1648 } 1648 }
1649 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1649 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1650 1650
1651 bool result_saved = false; // Is the result saved to the stack? 1651 bool result_saved = false; // Is the result saved to the stack?
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 for (; array_index < length; array_index++) { 1691 for (; array_index < length; array_index++) {
1692 Expression* subexpr = subexprs->at(array_index); 1692 Expression* subexpr = subexprs->at(array_index);
1693 1693
1694 __ Push(rax); 1694 __ Push(rax);
1695 if (subexpr->IsSpread()) { 1695 if (subexpr->IsSpread()) {
1696 VisitForStackValue(subexpr->AsSpread()->expression()); 1696 VisitForStackValue(subexpr->AsSpread()->expression());
1697 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, 1697 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
1698 CALL_FUNCTION); 1698 CALL_FUNCTION);
1699 } else { 1699 } else {
1700 VisitForStackValue(subexpr); 1700 VisitForStackValue(subexpr);
1701 __ CallRuntime(Runtime::kAppendElement, 2); 1701 __ CallRuntime(Runtime::kAppendElement);
1702 } 1702 }
1703 1703
1704 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1704 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1705 } 1705 }
1706 1706
1707 if (result_saved) { 1707 if (result_saved) {
1708 context()->PlugTOS(); 1708 context()->PlugTOS();
1709 } else { 1709 } else {
1710 context()->Plug(rax); 1710 context()->Plug(rax);
1711 } 1711 }
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2088 Label push_operand_holes, call_resume; 2088 Label push_operand_holes, call_resume;
2089 __ bind(&push_operand_holes); 2089 __ bind(&push_operand_holes);
2090 __ subp(rdx, Immediate(1)); 2090 __ subp(rdx, Immediate(1));
2091 __ j(carry, &call_resume); 2091 __ j(carry, &call_resume);
2092 __ Push(rcx); 2092 __ Push(rcx);
2093 __ jmp(&push_operand_holes); 2093 __ jmp(&push_operand_holes);
2094 __ bind(&call_resume); 2094 __ bind(&call_resume);
2095 __ Push(rbx); 2095 __ Push(rbx);
2096 __ Push(result_register()); 2096 __ Push(result_register());
2097 __ Push(Smi::FromInt(resume_mode)); 2097 __ Push(Smi::FromInt(resume_mode));
2098 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2098 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2099 // Not reached: the runtime call returns elsewhere. 2099 // Not reached: the runtime call returns elsewhere.
2100 __ Abort(kGeneratorFailedToResume); 2100 __ Abort(kGeneratorFailedToResume);
2101 2101
2102 __ bind(&done); 2102 __ bind(&done);
2103 context()->Plug(result_register()); 2103 context()->Plug(result_register());
2104 } 2104 }
2105 2105
2106 2106
2107 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2107 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2108 Label allocate, done_allocate; 2108 Label allocate, done_allocate;
2109 2109
2110 __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT); 2110 __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT);
2111 __ jmp(&done_allocate, Label::kNear); 2111 __ jmp(&done_allocate, Label::kNear);
2112 2112
2113 __ bind(&allocate); 2113 __ bind(&allocate);
2114 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2114 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2115 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 2115 __ CallRuntime(Runtime::kAllocateInNewSpace);
2116 2116
2117 __ bind(&done_allocate); 2117 __ bind(&done_allocate);
2118 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx); 2118 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx);
2119 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); 2119 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx);
2120 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); 2120 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
2121 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); 2121 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
2122 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); 2122 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx);
2123 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); 2123 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset));
2124 __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset), 2124 __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset),
2125 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); 2125 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
(...skipping 15 matching lines...) Expand all
2141 2141
2142 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2142 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2143 // Stack: receiver, home_object 2143 // Stack: receiver, home_object
2144 SetExpressionPosition(prop); 2144 SetExpressionPosition(prop);
2145 Literal* key = prop->key()->AsLiteral(); 2145 Literal* key = prop->key()->AsLiteral();
2146 DCHECK(!key->value()->IsSmi()); 2146 DCHECK(!key->value()->IsSmi());
2147 DCHECK(prop->IsSuperAccess()); 2147 DCHECK(prop->IsSuperAccess());
2148 2148
2149 __ Push(key->value()); 2149 __ Push(key->value());
2150 __ Push(Smi::FromInt(language_mode())); 2150 __ Push(Smi::FromInt(language_mode()));
2151 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2151 __ CallRuntime(Runtime::kLoadFromSuper);
2152 } 2152 }
2153 2153
2154 2154
2155 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2155 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2156 SetExpressionPosition(prop); 2156 SetExpressionPosition(prop);
2157 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); 2157 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
2158 __ Move(LoadDescriptor::SlotRegister(), 2158 __ Move(LoadDescriptor::SlotRegister(),
2159 SmiFromSlot(prop->PropertyFeedbackSlot())); 2159 SmiFromSlot(prop->PropertyFeedbackSlot()));
2160 CallIC(ic); 2160 CallIC(ic);
2161 } 2161 }
2162 2162
2163 2163
2164 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2164 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2165 // Stack: receiver, home_object, key. 2165 // Stack: receiver, home_object, key.
2166 SetExpressionPosition(prop); 2166 SetExpressionPosition(prop);
2167 __ Push(Smi::FromInt(language_mode())); 2167 __ Push(Smi::FromInt(language_mode()));
2168 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2168 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2169 } 2169 }
2170 2170
2171 2171
2172 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2172 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2173 Token::Value op, 2173 Token::Value op,
2174 Expression* left, 2174 Expression* left,
2175 Expression* right) { 2175 Expression* right) {
2176 // Do combined smi check of the operands. Left operand is on the 2176 // Do combined smi check of the operands. Left operand is on the
2177 // stack (popped into rdx). Right operand is in rax but moved into 2177 // stack (popped into rdx). Right operand is in rax but moved into
2178 // rcx to make the shifts easier. 2178 // rcx to make the shifts easier.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 } else { 2250 } else {
2251 __ Push(Operand(rsp, 0)); // prototype 2251 __ Push(Operand(rsp, 0)); // prototype
2252 } 2252 }
2253 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2253 EmitPropertyKey(property, lit->GetIdForProperty(i));
2254 2254
2255 // The static prototype property is read only. We handle the non computed 2255 // The static prototype property is read only. We handle the non computed
2256 // property name case in the parser. Since this is the only case where we 2256 // property name case in the parser. Since this is the only case where we
2257 // need to check for an own read only property we special case this so we do 2257 // need to check for an own read only property we special case this so we do
2258 // not need to do this for every property. 2258 // not need to do this for every property.
2259 if (property->is_static() && property->is_computed_name()) { 2259 if (property->is_static() && property->is_computed_name()) {
2260 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); 2260 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2261 __ Push(rax); 2261 __ Push(rax);
2262 } 2262 }
2263 2263
2264 VisitForStackValue(value); 2264 VisitForStackValue(value);
2265 if (NeedsHomeObject(value)) { 2265 if (NeedsHomeObject(value)) {
2266 EmitSetHomeObject(value, 2, property->GetSlot()); 2266 EmitSetHomeObject(value, 2, property->GetSlot());
2267 } 2267 }
2268 2268
2269 switch (property->kind()) { 2269 switch (property->kind()) {
2270 case ObjectLiteral::Property::CONSTANT: 2270 case ObjectLiteral::Property::CONSTANT:
2271 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2271 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2272 case ObjectLiteral::Property::PROTOTYPE: 2272 case ObjectLiteral::Property::PROTOTYPE:
2273 UNREACHABLE(); 2273 UNREACHABLE();
2274 case ObjectLiteral::Property::COMPUTED: 2274 case ObjectLiteral::Property::COMPUTED:
2275 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2275 __ CallRuntime(Runtime::kDefineClassMethod);
2276 break; 2276 break;
2277 2277
2278 case ObjectLiteral::Property::GETTER: 2278 case ObjectLiteral::Property::GETTER:
2279 __ Push(Smi::FromInt(DONT_ENUM)); 2279 __ Push(Smi::FromInt(DONT_ENUM));
2280 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 2280 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
2281 break; 2281 break;
2282 2282
2283 case ObjectLiteral::Property::SETTER: 2283 case ObjectLiteral::Property::SETTER:
2284 __ Push(Smi::FromInt(DONT_ENUM)); 2284 __ Push(Smi::FromInt(DONT_ENUM));
2285 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 2285 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
2286 break; 2286 break;
2287 2287
2288 default: 2288 default:
2289 UNREACHABLE(); 2289 UNREACHABLE();
2290 } 2290 }
2291 } 2291 }
2292 2292
2293 // Set both the prototype and constructor to have fast properties, and also 2293 // Set both the prototype and constructor to have fast properties, and also
2294 // freeze them in strong mode. 2294 // freeze them in strong mode.
2295 __ CallRuntime(Runtime::kFinalizeClassDefinition, 2); 2295 __ CallRuntime(Runtime::kFinalizeClassDefinition);
2296 } 2296 }
2297 2297
2298 2298
2299 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2299 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2300 __ Pop(rdx); 2300 __ Pop(rdx);
2301 Handle<Code> code = 2301 Handle<Code> code =
2302 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); 2302 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
2303 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2303 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2304 CallIC(code, expr->BinaryOperationFeedbackId()); 2304 CallIC(code, expr->BinaryOperationFeedbackId());
2305 patch_site.EmitPatchInfo(); 2305 patch_site.EmitPatchInfo();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 } else if (var->mode() == LET && op != Token::INIT) { 2410 } else if (var->mode() == LET && op != Token::INIT) {
2411 // Non-initializing assignment to let variable needs a write barrier. 2411 // Non-initializing assignment to let variable needs a write barrier.
2412 DCHECK(!var->IsLookupSlot()); 2412 DCHECK(!var->IsLookupSlot());
2413 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2413 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2414 Label assign; 2414 Label assign;
2415 MemOperand location = VarOperand(var, rcx); 2415 MemOperand location = VarOperand(var, rcx);
2416 __ movp(rdx, location); 2416 __ movp(rdx, location);
2417 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2417 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2418 __ j(not_equal, &assign, Label::kNear); 2418 __ j(not_equal, &assign, Label::kNear);
2419 __ Push(var->name()); 2419 __ Push(var->name());
2420 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2420 __ CallRuntime(Runtime::kThrowReferenceError);
2421 __ bind(&assign); 2421 __ bind(&assign);
2422 EmitStoreToStackLocalOrContextSlot(var, location); 2422 EmitStoreToStackLocalOrContextSlot(var, location);
2423 2423
2424 } else if (var->mode() == CONST && op != Token::INIT) { 2424 } else if (var->mode() == CONST && op != Token::INIT) {
2425 // Assignment to const variable needs a write barrier. 2425 // Assignment to const variable needs a write barrier.
2426 DCHECK(!var->IsLookupSlot()); 2426 DCHECK(!var->IsLookupSlot());
2427 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2427 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2428 Label const_error; 2428 Label const_error;
2429 MemOperand location = VarOperand(var, rcx); 2429 MemOperand location = VarOperand(var, rcx);
2430 __ movp(rdx, location); 2430 __ movp(rdx, location);
2431 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2431 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2432 __ j(not_equal, &const_error, Label::kNear); 2432 __ j(not_equal, &const_error, Label::kNear);
2433 __ Push(var->name()); 2433 __ Push(var->name());
2434 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2434 __ CallRuntime(Runtime::kThrowReferenceError);
2435 __ bind(&const_error); 2435 __ bind(&const_error);
2436 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2436 __ CallRuntime(Runtime::kThrowConstAssignError);
2437 2437
2438 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2438 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2439 // Initializing assignment to const {this} needs a write barrier. 2439 // Initializing assignment to const {this} needs a write barrier.
2440 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2440 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2441 Label uninitialized_this; 2441 Label uninitialized_this;
2442 MemOperand location = VarOperand(var, rcx); 2442 MemOperand location = VarOperand(var, rcx);
2443 __ movp(rdx, location); 2443 __ movp(rdx, location);
2444 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2444 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2445 __ j(equal, &uninitialized_this); 2445 __ j(equal, &uninitialized_this);
2446 __ Push(var->name()); 2446 __ Push(var->name());
2447 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2447 __ CallRuntime(Runtime::kThrowReferenceError);
2448 __ bind(&uninitialized_this); 2448 __ bind(&uninitialized_this);
2449 EmitStoreToStackLocalOrContextSlot(var, location); 2449 EmitStoreToStackLocalOrContextSlot(var, location);
2450 2450
2451 } else if (!var->is_const_mode() || 2451 } else if (!var->is_const_mode() ||
2452 (var->mode() == CONST && op == Token::INIT)) { 2452 (var->mode() == CONST && op == Token::INIT)) {
2453 if (var->IsLookupSlot()) { 2453 if (var->IsLookupSlot()) {
2454 // Assignment to var. 2454 // Assignment to var.
2455 __ Push(rax); // Value. 2455 __ Push(rax); // Value.
2456 __ Push(rsi); // Context. 2456 __ Push(rsi); // Context.
2457 __ Push(var->name()); 2457 __ Push(var->name());
2458 __ Push(Smi::FromInt(language_mode())); 2458 __ Push(Smi::FromInt(language_mode()));
2459 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2459 __ CallRuntime(Runtime::kStoreLookupSlot);
2460 } else { 2460 } else {
2461 // Assignment to var or initializing assignment to let/const in harmony 2461 // Assignment to var or initializing assignment to let/const in harmony
2462 // mode. 2462 // mode.
2463 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2463 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2464 MemOperand location = VarOperand(var, rcx); 2464 MemOperand location = VarOperand(var, rcx);
2465 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) { 2465 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) {
2466 // Check for an uninitialized let binding. 2466 // Check for an uninitialized let binding.
2467 __ movp(rdx, location); 2467 __ movp(rdx, location);
2468 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2468 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2469 __ Check(equal, kLetBindingReInitialization); 2469 __ Check(equal, kLetBindingReInitialization);
2470 } 2470 }
2471 EmitStoreToStackLocalOrContextSlot(var, location); 2471 EmitStoreToStackLocalOrContextSlot(var, location);
2472 } 2472 }
2473 2473
2474 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { 2474 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) {
2475 // Const initializers need a write barrier. 2475 // Const initializers need a write barrier.
2476 DCHECK(!var->IsParameter()); // No const parameters. 2476 DCHECK(!var->IsParameter()); // No const parameters.
2477 if (var->IsLookupSlot()) { 2477 if (var->IsLookupSlot()) {
2478 __ Push(rax); 2478 __ Push(rax);
2479 __ Push(rsi); 2479 __ Push(rsi);
2480 __ Push(var->name()); 2480 __ Push(var->name());
2481 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2481 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot);
2482 } else { 2482 } else {
2483 DCHECK(var->IsStackLocal() || var->IsContextSlot()); 2483 DCHECK(var->IsStackLocal() || var->IsContextSlot());
2484 Label skip; 2484 Label skip;
2485 MemOperand location = VarOperand(var, rcx); 2485 MemOperand location = VarOperand(var, rcx);
2486 __ movp(rdx, location); 2486 __ movp(rdx, location);
2487 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2487 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2488 __ j(not_equal, &skip); 2488 __ j(not_equal, &skip);
2489 EmitStoreToStackLocalOrContextSlot(var, location); 2489 EmitStoreToStackLocalOrContextSlot(var, location);
2490 __ bind(&skip); 2490 __ bind(&skip);
2491 } 2491 }
2492 2492
2493 } else { 2493 } else {
2494 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); 2494 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT);
2495 if (is_strict(language_mode())) { 2495 if (is_strict(language_mode())) {
2496 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2496 __ CallRuntime(Runtime::kThrowConstAssignError);
2497 } 2497 }
2498 // Silently ignore store in sloppy mode. 2498 // Silently ignore store in sloppy mode.
2499 } 2499 }
2500 } 2500 }
2501 2501
2502 2502
2503 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2503 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2504 // Assignment to a property, using a named store IC. 2504 // Assignment to a property, using a named store IC.
2505 Property* prop = expr->target()->AsProperty(); 2505 Property* prop = expr->target()->AsProperty();
2506 DCHECK(prop != NULL); 2506 DCHECK(prop != NULL);
(...skipping 13 matching lines...) Expand all
2520 // Assignment to named property of super. 2520 // Assignment to named property of super.
2521 // rax : value 2521 // rax : value
2522 // stack : receiver ('this'), home_object 2522 // stack : receiver ('this'), home_object
2523 DCHECK(prop != NULL); 2523 DCHECK(prop != NULL);
2524 Literal* key = prop->key()->AsLiteral(); 2524 Literal* key = prop->key()->AsLiteral();
2525 DCHECK(key != NULL); 2525 DCHECK(key != NULL);
2526 2526
2527 __ Push(key->value()); 2527 __ Push(key->value());
2528 __ Push(rax); 2528 __ Push(rax);
2529 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2529 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
2530 : Runtime::kStoreToSuper_Sloppy), 2530 : Runtime::kStoreToSuper_Sloppy));
2531 4);
2532 } 2531 }
2533 2532
2534 2533
2535 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2534 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2536 // Assignment to named property of super. 2535 // Assignment to named property of super.
2537 // rax : value 2536 // rax : value
2538 // stack : receiver ('this'), home_object, key 2537 // stack : receiver ('this'), home_object, key
2539 DCHECK(prop != NULL); 2538 DCHECK(prop != NULL);
2540 2539
2541 __ Push(rax); 2540 __ Push(rax);
2542 __ CallRuntime( 2541 __ CallRuntime((is_strict(language_mode())
2543 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 2542 ? Runtime::kStoreKeyedToSuper_Strict
2544 : Runtime::kStoreKeyedToSuper_Sloppy), 2543 : Runtime::kStoreKeyedToSuper_Sloppy));
2545 4);
2546 } 2544 }
2547 2545
2548 2546
2549 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2547 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2550 // Assignment to a property, using a keyed store IC. 2548 // Assignment to a property, using a keyed store IC.
2551 __ Pop(StoreDescriptor::NameRegister()); // Key. 2549 __ Pop(StoreDescriptor::NameRegister()); // Key.
2552 __ Pop(StoreDescriptor::ReceiverRegister()); 2550 __ Pop(StoreDescriptor::ReceiverRegister());
2553 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 2551 DCHECK(StoreDescriptor::ValueRegister().is(rax));
2554 Handle<Code> ic = 2552 Handle<Code> ic =
2555 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2553 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 __ Push(key->value()); 2655 __ Push(key->value());
2658 __ Push(Smi::FromInt(language_mode())); 2656 __ Push(Smi::FromInt(language_mode()));
2659 2657
2660 // Stack here: 2658 // Stack here:
2661 // - home_object 2659 // - home_object
2662 // - this (receiver) 2660 // - this (receiver)
2663 // - this (receiver) <-- LoadFromSuper will pop here and below. 2661 // - this (receiver) <-- LoadFromSuper will pop here and below.
2664 // - home_object 2662 // - home_object
2665 // - key 2663 // - key
2666 // - language_mode 2664 // - language_mode
2667 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2665 __ CallRuntime(Runtime::kLoadFromSuper);
2668 2666
2669 // Replace home_object with target function. 2667 // Replace home_object with target function.
2670 __ movp(Operand(rsp, kPointerSize), rax); 2668 __ movp(Operand(rsp, kPointerSize), rax);
2671 2669
2672 // Stack here: 2670 // Stack here:
2673 // - target function 2671 // - target function
2674 // - this (receiver) 2672 // - this (receiver)
2675 EmitCall(expr); 2673 EmitCall(expr);
2676 } 2674 }
2677 2675
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 VisitForStackValue(prop->key()); 2714 VisitForStackValue(prop->key());
2717 __ Push(Smi::FromInt(language_mode())); 2715 __ Push(Smi::FromInt(language_mode()));
2718 2716
2719 // Stack here: 2717 // Stack here:
2720 // - home_object 2718 // - home_object
2721 // - this (receiver) 2719 // - this (receiver)
2722 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2720 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2723 // - home_object 2721 // - home_object
2724 // - key 2722 // - key
2725 // - language_mode 2723 // - language_mode
2726 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2724 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2727 2725
2728 // Replace home_object with target function. 2726 // Replace home_object with target function.
2729 __ movp(Operand(rsp, kPointerSize), rax); 2727 __ movp(Operand(rsp, kPointerSize), rax);
2730 2728
2731 // Stack here: 2729 // Stack here:
2732 // - target function 2730 // - target function
2733 // - this (receiver) 2731 // - this (receiver)
2734 EmitCall(expr); 2732 EmitCall(expr);
2735 } 2733 }
2736 2734
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2772 // Push the enclosing function. 2770 // Push the enclosing function.
2773 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 2771 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
2774 2772
2775 // Push the language mode. 2773 // Push the language mode.
2776 __ Push(Smi::FromInt(language_mode())); 2774 __ Push(Smi::FromInt(language_mode()));
2777 2775
2778 // Push the start position of the scope the calls resides in. 2776 // Push the start position of the scope the calls resides in.
2779 __ Push(Smi::FromInt(scope()->start_position())); 2777 __ Push(Smi::FromInt(scope()->start_position()));
2780 2778
2781 // Do the runtime call. 2779 // Do the runtime call.
2782 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2780 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2783 } 2781 }
2784 2782
2785 2783
2786 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. 2784 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2787 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { 2785 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2788 VariableProxy* callee = expr->expression()->AsVariableProxy(); 2786 VariableProxy* callee = expr->expression()->AsVariableProxy();
2789 if (callee->var()->IsLookupSlot()) { 2787 if (callee->var()->IsLookupSlot()) {
2790 Label slow, done; 2788 Label slow, done;
2791 SetExpressionPosition(callee); 2789 SetExpressionPosition(callee);
2792 // Generate code for loading from variables potentially shadowed by 2790 // Generate code for loading from variables potentially shadowed by
2793 // eval-introduced variables. 2791 // eval-introduced variables.
2794 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2792 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2795 __ bind(&slow); 2793 __ bind(&slow);
2796 // Call the runtime to find the function to call (returned in rax) and 2794 // Call the runtime to find the function to call (returned in rax) and
2797 // the object holding it (returned in rdx). 2795 // the object holding it (returned in rdx).
2798 __ Push(context_register()); 2796 __ Push(context_register());
2799 __ Push(callee->name()); 2797 __ Push(callee->name());
2800 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2798 __ CallRuntime(Runtime::kLoadLookupSlot);
2801 __ Push(rax); // Function. 2799 __ Push(rax); // Function.
2802 __ Push(rdx); // Receiver. 2800 __ Push(rdx); // Receiver.
2803 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2801 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2804 2802
2805 // If fast case code has been generated, emit code to push the function 2803 // If fast case code has been generated, emit code to push the function
2806 // and receiver and have the slow path jump around this code. 2804 // and receiver and have the slow path jump around this code.
2807 if (done.is_linked()) { 2805 if (done.is_linked()) {
2808 Label call; 2806 Label call;
2809 __ jmp(&call, Label::kNear); 2807 __ jmp(&call, Label::kNear);
2810 __ bind(&done); 2808 __ bind(&done);
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
3439 ZoneList<Expression*>* args = expr->arguments(); 3437 ZoneList<Expression*>* args = expr->arguments();
3440 DCHECK_EQ(1, args->length()); 3438 DCHECK_EQ(1, args->length());
3441 3439
3442 // Load the argument into rax and convert it. 3440 // Load the argument into rax and convert it.
3443 VisitForAccumulatorValue(args->at(0)); 3441 VisitForAccumulatorValue(args->at(0));
3444 3442
3445 // Convert the object to an integer. 3443 // Convert the object to an integer.
3446 Label done_convert; 3444 Label done_convert;
3447 __ JumpIfSmi(rax, &done_convert, Label::kNear); 3445 __ JumpIfSmi(rax, &done_convert, Label::kNear);
3448 __ Push(rax); 3446 __ Push(rax);
3449 __ CallRuntime(Runtime::kToInteger, 1); 3447 __ CallRuntime(Runtime::kToInteger);
3450 __ bind(&done_convert); 3448 __ bind(&done_convert);
3451 context()->Plug(rax); 3449 context()->Plug(rax);
3452 } 3450 }
3453 3451
3454 3452
3455 void FullCodeGenerator::EmitToName(CallRuntime* expr) { 3453 void FullCodeGenerator::EmitToName(CallRuntime* expr) {
3456 ZoneList<Expression*>* args = expr->arguments(); 3454 ZoneList<Expression*>* args = expr->arguments();
3457 DCHECK_EQ(1, args->length()); 3455 DCHECK_EQ(1, args->length());
3458 3456
3459 // Load the argument into rax and convert it. 3457 // Load the argument into rax and convert it.
3460 VisitForAccumulatorValue(args->at(0)); 3458 VisitForAccumulatorValue(args->at(0));
3461 3459
3462 // Convert the object to a name. 3460 // Convert the object to a name.
3463 Label convert, done_convert; 3461 Label convert, done_convert;
3464 __ JumpIfSmi(rax, &convert, Label::kNear); 3462 __ JumpIfSmi(rax, &convert, Label::kNear);
3465 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 3463 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
3466 __ CmpObjectType(rax, LAST_NAME_TYPE, rcx); 3464 __ CmpObjectType(rax, LAST_NAME_TYPE, rcx);
3467 __ j(below_equal, &done_convert, Label::kNear); 3465 __ j(below_equal, &done_convert, Label::kNear);
3468 __ bind(&convert); 3466 __ bind(&convert);
3469 __ Push(rax); 3467 __ Push(rax);
3470 __ CallRuntime(Runtime::kToName, 1); 3468 __ CallRuntime(Runtime::kToName);
3471 __ bind(&done_convert); 3469 __ bind(&done_convert);
3472 context()->Plug(rax); 3470 context()->Plug(rax);
3473 } 3471 }
3474 3472
3475 3473
3476 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3474 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3477 ZoneList<Expression*>* args = expr->arguments(); 3475 ZoneList<Expression*>* args = expr->arguments();
3478 DCHECK(args->length() == 1); 3476 DCHECK(args->length() == 1);
3479 3477
3480 VisitForAccumulatorValue(args->at(0)); 3478 VisitForAccumulatorValue(args->at(0));
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
3970 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); 3968 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx);
3971 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); 3969 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
3972 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); 3970 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
3973 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); 3971 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx);
3974 __ Pop(FieldOperand(rax, JSIteratorResult::kDoneOffset)); 3972 __ Pop(FieldOperand(rax, JSIteratorResult::kDoneOffset));
3975 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); 3973 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset));
3976 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3974 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3977 __ jmp(&done, Label::kNear); 3975 __ jmp(&done, Label::kNear);
3978 3976
3979 __ bind(&runtime); 3977 __ bind(&runtime);
3980 __ CallRuntime(Runtime::kCreateIterResultObject, 2); 3978 __ CallRuntime(Runtime::kCreateIterResultObject);
3981 3979
3982 __ bind(&done); 3980 __ bind(&done);
3983 context()->Plug(rax); 3981 context()->Plug(rax);
3984 } 3982 }
3985 3983
3986 3984
3987 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3985 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3988 // Push the builtins object as receiver. 3986 // Push the builtins object as receiver.
3989 __ PushRoot(Heap::kUndefinedValueRootIndex); 3987 __ PushRoot(Heap::kUndefinedValueRootIndex);
3990 3988
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4061 case Token::DELETE: { 4059 case Token::DELETE: {
4062 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4060 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4063 Property* property = expr->expression()->AsProperty(); 4061 Property* property = expr->expression()->AsProperty();
4064 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4062 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4065 4063
4066 if (property != NULL) { 4064 if (property != NULL) {
4067 VisitForStackValue(property->obj()); 4065 VisitForStackValue(property->obj());
4068 VisitForStackValue(property->key()); 4066 VisitForStackValue(property->key());
4069 __ CallRuntime(is_strict(language_mode()) 4067 __ CallRuntime(is_strict(language_mode())
4070 ? Runtime::kDeleteProperty_Strict 4068 ? Runtime::kDeleteProperty_Strict
4071 : Runtime::kDeleteProperty_Sloppy, 4069 : Runtime::kDeleteProperty_Sloppy);
4072 2);
4073 context()->Plug(rax); 4070 context()->Plug(rax);
4074 } else if (proxy != NULL) { 4071 } else if (proxy != NULL) {
4075 Variable* var = proxy->var(); 4072 Variable* var = proxy->var();
4076 // Delete of an unqualified identifier is disallowed in strict mode but 4073 // Delete of an unqualified identifier is disallowed in strict mode but
4077 // "delete this" is allowed. 4074 // "delete this" is allowed.
4078 bool is_this = var->HasThisName(isolate()); 4075 bool is_this = var->HasThisName(isolate());
4079 DCHECK(is_sloppy(language_mode()) || is_this); 4076 DCHECK(is_sloppy(language_mode()) || is_this);
4080 if (var->IsUnallocatedOrGlobalSlot()) { 4077 if (var->IsUnallocatedOrGlobalSlot()) {
4081 __ movp(rax, NativeContextOperand()); 4078 __ movp(rax, NativeContextOperand());
4082 __ Push(ContextOperand(rax, Context::EXTENSION_INDEX)); 4079 __ Push(ContextOperand(rax, Context::EXTENSION_INDEX));
4083 __ Push(var->name()); 4080 __ Push(var->name());
4084 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); 4081 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
4085 context()->Plug(rax); 4082 context()->Plug(rax);
4086 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4083 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4087 // Result of deleting non-global variables is false. 'this' is 4084 // Result of deleting non-global variables is false. 'this' is
4088 // not really a variable, though we implement it as one. The 4085 // not really a variable, though we implement it as one. The
4089 // subexpression does not have side effects. 4086 // subexpression does not have side effects.
4090 context()->Plug(is_this); 4087 context()->Plug(is_this);
4091 } else { 4088 } else {
4092 // Non-global variable. Call the runtime to try to delete from the 4089 // Non-global variable. Call the runtime to try to delete from the
4093 // context where the variable was introduced. 4090 // context where the variable was introduced.
4094 __ Push(context_register()); 4091 __ Push(context_register());
4095 __ Push(var->name()); 4092 __ Push(var->name());
4096 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 4093 __ CallRuntime(Runtime::kDeleteLookupSlot);
4097 context()->Plug(rax); 4094 context()->Plug(rax);
4098 } 4095 }
4099 } else { 4096 } else {
4100 // Result of deleting non-property, non-variable reference is true. 4097 // Result of deleting non-property, non-variable reference is true.
4101 // The subexpression may have side effects. 4098 // The subexpression may have side effects.
4102 VisitForEffect(expr->expression()); 4099 VisitForEffect(expr->expression());
4103 context()->Plug(true); 4100 context()->Plug(true);
4104 } 4101 }
4105 break; 4102 break;
4106 } 4103 }
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
4521 Label* if_false = NULL; 4518 Label* if_false = NULL;
4522 Label* fall_through = NULL; 4519 Label* fall_through = NULL;
4523 context()->PrepareTest(&materialize_true, &materialize_false, 4520 context()->PrepareTest(&materialize_true, &materialize_false,
4524 &if_true, &if_false, &fall_through); 4521 &if_true, &if_false, &fall_through);
4525 4522
4526 Token::Value op = expr->op(); 4523 Token::Value op = expr->op();
4527 VisitForStackValue(expr->left()); 4524 VisitForStackValue(expr->left());
4528 switch (op) { 4525 switch (op) {
4529 case Token::IN: 4526 case Token::IN:
4530 VisitForStackValue(expr->right()); 4527 VisitForStackValue(expr->right());
4531 __ CallRuntime(Runtime::kHasProperty, 2); 4528 __ CallRuntime(Runtime::kHasProperty);
4532 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4529 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4533 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 4530 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
4534 Split(equal, if_true, if_false, fall_through); 4531 Split(equal, if_true, if_false, fall_through);
4535 break; 4532 break;
4536 4533
4537 case Token::INSTANCEOF: { 4534 case Token::INSTANCEOF: {
4538 VisitForAccumulatorValue(expr->right()); 4535 VisitForAccumulatorValue(expr->right());
4539 __ Pop(rdx); 4536 __ Pop(rdx);
4540 InstanceOfStub stub(isolate()); 4537 InstanceOfStub stub(isolate());
4541 __ CallStub(&stub); 4538 __ CallStub(&stub);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
4795 Assembler::target_address_at(call_target_address, 4792 Assembler::target_address_at(call_target_address,
4796 unoptimized_code)); 4793 unoptimized_code));
4797 return OSR_AFTER_STACK_CHECK; 4794 return OSR_AFTER_STACK_CHECK;
4798 } 4795 }
4799 4796
4800 4797
4801 } // namespace internal 4798 } // namespace internal
4802 } // namespace v8 4799 } // namespace v8
4803 4800
4804 #endif // V8_TARGET_ARCH_X64 4801 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698