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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 246643014: CodeStubs contain their corresponding Isolate* now. (part 1) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Feedback. Rebased. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 descriptor->param_representations_ = representations; 475 descriptor->param_representations_ = representations;
476 } 476 }
477 } 477 }
478 478
479 479
480 #define __ ACCESS_MASM(masm) 480 #define __ ACCESS_MASM(masm)
481 481
482 482
483 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 483 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
484 // Update the static counter each time a new code stub is generated. 484 // Update the static counter each time a new code stub is generated.
485 Isolate* isolate = masm->isolate(); 485 isolate()->counters()->code_stubs()->Increment();
486 isolate->counters()->code_stubs()->Increment();
487 486
488 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); 487 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate());
489 int param_count = descriptor->register_param_count_; 488 int param_count = descriptor->register_param_count_;
490 { 489 {
491 // Call the runtime system in a fresh internal frame. 490 // Call the runtime system in a fresh internal frame.
492 FrameScope scope(masm, StackFrame::INTERNAL); 491 FrameScope scope(masm, StackFrame::INTERNAL);
493 ASSERT(descriptor->register_param_count_ == 0 || 492 ASSERT(descriptor->register_param_count_ == 0 ||
494 eax.is(descriptor->register_params_[param_count - 1])); 493 eax.is(descriptor->register_params_[param_count - 1]));
495 // Push arguments 494 // Push arguments
496 for (int i = 0; i < param_count; ++i) { 495 for (int i = 0; i < param_count; ++i) {
497 __ push(descriptor->register_params_[i]); 496 __ push(descriptor->register_params_[i]);
498 } 497 }
(...skipping 16 matching lines...) Expand all
515 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 514 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
516 XMMRegister reg = XMMRegister::from_code(i); 515 XMMRegister reg = XMMRegister::from_code(i);
517 __ movsd(Operand(esp, i * kDoubleSize), reg); 516 __ movsd(Operand(esp, i * kDoubleSize), reg);
518 } 517 }
519 } 518 }
520 const int argument_count = 1; 519 const int argument_count = 1;
521 520
522 AllowExternalCallThatCantCauseGC scope(masm); 521 AllowExternalCallThatCantCauseGC scope(masm);
523 __ PrepareCallCFunction(argument_count, ecx); 522 __ PrepareCallCFunction(argument_count, ecx);
524 __ mov(Operand(esp, 0 * kPointerSize), 523 __ mov(Operand(esp, 0 * kPointerSize),
525 Immediate(ExternalReference::isolate_address(masm->isolate()))); 524 Immediate(ExternalReference::isolate_address(isolate())));
526 __ CallCFunction( 525 __ CallCFunction(
527 ExternalReference::store_buffer_overflow_function(masm->isolate()), 526 ExternalReference::store_buffer_overflow_function(isolate()),
528 argument_count); 527 argument_count);
529 if (save_doubles_ == kSaveFPRegs) { 528 if (save_doubles_ == kSaveFPRegs) {
530 CpuFeatureScope scope(masm, SSE2); 529 CpuFeatureScope scope(masm, SSE2);
531 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 530 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
532 XMMRegister reg = XMMRegister::from_code(i); 531 XMMRegister reg = XMMRegister::from_code(i);
533 __ movsd(reg, Operand(esp, i * kDoubleSize)); 532 __ movsd(reg, Operand(esp, i * kDoubleSize));
534 } 533 }
535 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 534 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
536 } 535 }
537 __ popad(); 536 __ popad();
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 __ cmp(scratch, factory->heap_number_map()); 773 __ cmp(scratch, factory->heap_number_map());
775 __ j(not_equal, non_float); // argument in eax is not a number -> NaN 774 __ j(not_equal, non_float); // argument in eax is not a number -> NaN
776 775
777 // Fall-through: Both operands are numbers. 776 // Fall-through: Both operands are numbers.
778 __ bind(&done); 777 __ bind(&done);
779 } 778 }
780 779
781 780
782 void MathPowStub::Generate(MacroAssembler* masm) { 781 void MathPowStub::Generate(MacroAssembler* masm) {
783 CpuFeatureScope use_sse2(masm, SSE2); 782 CpuFeatureScope use_sse2(masm, SSE2);
784 Factory* factory = masm->isolate()->factory(); 783 Factory* factory = isolate()->factory();
785 const Register exponent = eax; 784 const Register exponent = eax;
786 const Register base = edx; 785 const Register base = edx;
787 const Register scratch = ecx; 786 const Register scratch = ecx;
788 const XMMRegister double_result = xmm3; 787 const XMMRegister double_result = xmm3;
789 const XMMRegister double_base = xmm2; 788 const XMMRegister double_base = xmm2;
790 const XMMRegister double_exponent = xmm1; 789 const XMMRegister double_exponent = xmm1;
791 const XMMRegister double_scratch = xmm4; 790 const XMMRegister double_scratch = xmm4;
792 791
793 Label call_runtime, done, exponent_not_smi, int_exponent; 792 Label call_runtime, done, exponent_not_smi, int_exponent;
794 793
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. 1002 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
1004 __ xorps(double_scratch2, double_scratch2); 1003 __ xorps(double_scratch2, double_scratch2);
1005 __ ucomisd(double_scratch2, double_result); // Result cannot be NaN. 1004 __ ucomisd(double_scratch2, double_result); // Result cannot be NaN.
1006 // double_exponent aliased as double_scratch2 has already been overwritten 1005 // double_exponent aliased as double_scratch2 has already been overwritten
1007 // and may not have contained the exponent value in the first place when the 1006 // and may not have contained the exponent value in the first place when the
1008 // exponent is a smi. We reset it with exponent value before bailing out. 1007 // exponent is a smi. We reset it with exponent value before bailing out.
1009 __ j(not_equal, &done); 1008 __ j(not_equal, &done);
1010 __ Cvtsi2sd(double_exponent, exponent); 1009 __ Cvtsi2sd(double_exponent, exponent);
1011 1010
1012 // Returning or bailing out. 1011 // Returning or bailing out.
1013 Counters* counters = masm->isolate()->counters(); 1012 Counters* counters = isolate()->counters();
1014 if (exponent_type_ == ON_STACK) { 1013 if (exponent_type_ == ON_STACK) {
1015 // The arguments are still on the stack. 1014 // The arguments are still on the stack.
1016 __ bind(&call_runtime); 1015 __ bind(&call_runtime);
1017 __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1); 1016 __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
1018 1017
1019 // The stub is called from non-optimized code, which expects the result 1018 // The stub is called from non-optimized code, which expects the result
1020 // as heap number in exponent. 1019 // as heap number in exponent.
1021 __ bind(&done); 1020 __ bind(&done);
1022 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); 1021 __ AllocateHeapNumber(eax, scratch, base, &call_runtime);
1023 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result); 1022 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result);
1024 __ IncrementCounter(counters->math_pow(), 1); 1023 __ IncrementCounter(counters->math_pow(), 1);
1025 __ ret(2 * kPointerSize); 1024 __ ret(2 * kPointerSize);
1026 } else { 1025 } else {
1027 __ bind(&call_runtime); 1026 __ bind(&call_runtime);
1028 { 1027 {
1029 AllowExternalCallThatCantCauseGC scope(masm); 1028 AllowExternalCallThatCantCauseGC scope(masm);
1030 __ PrepareCallCFunction(4, scratch); 1029 __ PrepareCallCFunction(4, scratch);
1031 __ movsd(Operand(esp, 0 * kDoubleSize), double_base); 1030 __ movsd(Operand(esp, 0 * kDoubleSize), double_base);
1032 __ movsd(Operand(esp, 1 * kDoubleSize), double_exponent); 1031 __ movsd(Operand(esp, 1 * kDoubleSize), double_exponent);
1033 __ CallCFunction( 1032 __ CallCFunction(
1034 ExternalReference::power_double_double_function(masm->isolate()), 4); 1033 ExternalReference::power_double_double_function(isolate()), 4);
1035 } 1034 }
1036 // Return value is in st(0) on ia32. 1035 // Return value is in st(0) on ia32.
1037 // Store it into the (fixed) result register. 1036 // Store it into the (fixed) result register.
1038 __ sub(esp, Immediate(kDoubleSize)); 1037 __ sub(esp, Immediate(kDoubleSize));
1039 __ fstp_d(Operand(esp, 0)); 1038 __ fstp_d(Operand(esp, 0));
1040 __ movsd(double_result, Operand(esp, 0)); 1039 __ movsd(double_result, Operand(esp, 0));
1041 __ add(esp, Immediate(kDoubleSize)); 1040 __ add(esp, Immediate(kDoubleSize));
1042 1041
1043 __ bind(&done); 1042 __ bind(&done);
1044 __ IncrementCounter(counters->math_pow(), 1); 1043 __ IncrementCounter(counters->math_pow(), 1);
1045 __ ret(0); 1044 __ ret(0);
1046 } 1045 }
1047 } 1046 }
1048 1047
1049 1048
1050 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 1049 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
1051 // ----------- S t a t e ------------- 1050 // ----------- S t a t e -------------
1052 // -- ecx : name 1051 // -- ecx : name
1053 // -- edx : receiver 1052 // -- edx : receiver
1054 // -- esp[0] : return address 1053 // -- esp[0] : return address
1055 // ----------------------------------- 1054 // -----------------------------------
1056 Label miss; 1055 Label miss;
1057 1056
1058 if (kind() == Code::KEYED_LOAD_IC) { 1057 if (kind() == Code::KEYED_LOAD_IC) {
1059 __ cmp(ecx, Immediate(masm->isolate()->factory()->prototype_string())); 1058 __ cmp(ecx, Immediate(isolate()->factory()->prototype_string()));
1060 __ j(not_equal, &miss); 1059 __ j(not_equal, &miss);
1061 } 1060 }
1062 1061
1063 StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss); 1062 StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss);
1064 __ bind(&miss); 1063 __ bind(&miss);
1065 StubCompiler::TailCallBuiltin( 1064 StubCompiler::TailCallBuiltin(
1066 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); 1065 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
1067 } 1066 }
1068 1067
1069 1068
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 __ lea(edx, Operand(edx, ecx, times_2, 1144 __ lea(edx, Operand(edx, ecx, times_2,
1146 StandardFrameConstants::kCallerSPOffset)); 1145 StandardFrameConstants::kCallerSPOffset));
1147 __ mov(Operand(esp, 2 * kPointerSize), edx); 1146 __ mov(Operand(esp, 2 * kPointerSize), edx);
1148 1147
1149 __ bind(&runtime); 1148 __ bind(&runtime);
1150 __ TailCallRuntime(Runtime::kHiddenNewArgumentsFast, 3, 1); 1149 __ TailCallRuntime(Runtime::kHiddenNewArgumentsFast, 3, 1);
1151 } 1150 }
1152 1151
1153 1152
1154 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { 1153 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
1155 Isolate* isolate = masm->isolate();
1156
1157 // esp[0] : return address 1154 // esp[0] : return address
1158 // esp[4] : number of parameters (tagged) 1155 // esp[4] : number of parameters (tagged)
1159 // esp[8] : receiver displacement 1156 // esp[8] : receiver displacement
1160 // esp[12] : function 1157 // esp[12] : function
1161 1158
1162 // ebx = parameter count (tagged) 1159 // ebx = parameter count (tagged)
1163 __ mov(ebx, Operand(esp, 1 * kPointerSize)); 1160 __ mov(ebx, Operand(esp, 1 * kPointerSize));
1164 1161
1165 // Check if the calling frame is an arguments adaptor frame. 1162 // Check if the calling frame is an arguments adaptor frame.
1166 // TODO(rossberg): Factor out some of the bits that are shared with the other 1163 // TODO(rossberg): Factor out some of the bits that are shared with the other
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 // esp[12] = address of receiver argument 1275 // esp[12] = address of receiver argument
1279 // Free a register. 1276 // Free a register.
1280 __ push(eax); 1277 __ push(eax);
1281 1278
1282 // Initialize parameter map. If there are no mapped arguments, we're done. 1279 // Initialize parameter map. If there are no mapped arguments, we're done.
1283 Label skip_parameter_map; 1280 Label skip_parameter_map;
1284 __ test(ebx, ebx); 1281 __ test(ebx, ebx);
1285 __ j(zero, &skip_parameter_map); 1282 __ j(zero, &skip_parameter_map);
1286 1283
1287 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 1284 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1288 Immediate(isolate->factory()->sloppy_arguments_elements_map())); 1285 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
1289 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2)))); 1286 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
1290 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax); 1287 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
1291 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi); 1288 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
1292 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize)); 1289 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
1293 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax); 1290 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
1294 1291
1295 // Copy the parameter slots and the holes in the arguments. 1292 // Copy the parameter slots and the holes in the arguments.
1296 // We need to fill in mapped_parameter_count slots. They index the context, 1293 // We need to fill in mapped_parameter_count slots. They index the context,
1297 // where parameters are stored in reverse order, at 1294 // where parameters are stored in reverse order, at
1298 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 1295 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
1299 // The mapped parameter thus need to get indices 1296 // The mapped parameter thus need to get indices
1300 // MIN_CONTEXT_SLOTS+parameter_count-1 .. 1297 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
1301 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count 1298 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
1302 // We loop from right to left. 1299 // We loop from right to left.
1303 Label parameters_loop, parameters_test; 1300 Label parameters_loop, parameters_test;
1304 __ push(ecx); 1301 __ push(ecx);
1305 __ mov(eax, Operand(esp, 2 * kPointerSize)); 1302 __ mov(eax, Operand(esp, 2 * kPointerSize));
1306 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); 1303 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
1307 __ add(ebx, Operand(esp, 4 * kPointerSize)); 1304 __ add(ebx, Operand(esp, 4 * kPointerSize));
1308 __ sub(ebx, eax); 1305 __ sub(ebx, eax);
1309 __ mov(ecx, isolate->factory()->the_hole_value()); 1306 __ mov(ecx, isolate()->factory()->the_hole_value());
1310 __ mov(edx, edi); 1307 __ mov(edx, edi);
1311 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize)); 1308 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
1312 // eax = loop variable (tagged) 1309 // eax = loop variable (tagged)
1313 // ebx = mapping index (tagged) 1310 // ebx = mapping index (tagged)
1314 // ecx = the hole value 1311 // ecx = the hole value
1315 // edx = address of parameter map (tagged) 1312 // edx = address of parameter map (tagged)
1316 // edi = address of backing store (tagged) 1313 // edi = address of backing store (tagged)
1317 // esp[0] = argument count (tagged) 1314 // esp[0] = argument count (tagged)
1318 // esp[4] = address of new object (tagged) 1315 // esp[4] = address of new object (tagged)
1319 // esp[8] = mapped parameter count (tagged) 1316 // esp[8] = mapped parameter count (tagged)
(...skipping 14 matching lines...) Expand all
1334 __ bind(&skip_parameter_map); 1331 __ bind(&skip_parameter_map);
1335 1332
1336 // ecx = argument count (tagged) 1333 // ecx = argument count (tagged)
1337 // edi = address of backing store (tagged) 1334 // edi = address of backing store (tagged)
1338 // esp[0] = address of new object (tagged) 1335 // esp[0] = address of new object (tagged)
1339 // esp[4] = mapped parameter count (tagged) 1336 // esp[4] = mapped parameter count (tagged)
1340 // esp[12] = parameter count (tagged) 1337 // esp[12] = parameter count (tagged)
1341 // esp[16] = address of receiver argument 1338 // esp[16] = address of receiver argument
1342 // Copy arguments header and remaining slots (if there are any). 1339 // Copy arguments header and remaining slots (if there are any).
1343 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 1340 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1344 Immediate(isolate->factory()->fixed_array_map())); 1341 Immediate(isolate()->factory()->fixed_array_map()));
1345 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); 1342 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1346 1343
1347 Label arguments_loop, arguments_test; 1344 Label arguments_loop, arguments_test;
1348 __ mov(ebx, Operand(esp, 1 * kPointerSize)); 1345 __ mov(ebx, Operand(esp, 1 * kPointerSize));
1349 __ mov(edx, Operand(esp, 4 * kPointerSize)); 1346 __ mov(edx, Operand(esp, 4 * kPointerSize));
1350 __ sub(edx, ebx); // Is there a smarter way to do negative scaling? 1347 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
1351 __ sub(edx, ebx); 1348 __ sub(edx, ebx);
1352 __ jmp(&arguments_test, Label::kNear); 1349 __ jmp(&arguments_test, Label::kNear);
1353 1350
1354 __ bind(&arguments_loop); 1351 __ bind(&arguments_loop);
(...skipping 15 matching lines...) Expand all
1370 1367
1371 // Do the runtime call to allocate the arguments object. 1368 // Do the runtime call to allocate the arguments object.
1372 __ bind(&runtime); 1369 __ bind(&runtime);
1373 __ pop(eax); // Remove saved parameter count. 1370 __ pop(eax); // Remove saved parameter count.
1374 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. 1371 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count.
1375 __ TailCallRuntime(Runtime::kHiddenNewArgumentsFast, 3, 1); 1372 __ TailCallRuntime(Runtime::kHiddenNewArgumentsFast, 3, 1);
1376 } 1373 }
1377 1374
1378 1375
1379 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 1376 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
1380 Isolate* isolate = masm->isolate();
1381
1382 // esp[0] : return address 1377 // esp[0] : return address
1383 // esp[4] : number of parameters 1378 // esp[4] : number of parameters
1384 // esp[8] : receiver displacement 1379 // esp[8] : receiver displacement
1385 // esp[12] : function 1380 // esp[12] : function
1386 1381
1387 // Check if the calling frame is an arguments adaptor frame. 1382 // Check if the calling frame is an arguments adaptor frame.
1388 Label adaptor_frame, try_allocate, runtime; 1383 Label adaptor_frame, try_allocate, runtime;
1389 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 1384 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1390 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 1385 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
1391 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1386 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 __ j(zero, &done, Label::kNear); 1437 __ j(zero, &done, Label::kNear);
1443 1438
1444 // Get the parameters pointer from the stack. 1439 // Get the parameters pointer from the stack.
1445 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1440 __ mov(edx, Operand(esp, 2 * kPointerSize));
1446 1441
1447 // Set up the elements pointer in the allocated arguments object and 1442 // Set up the elements pointer in the allocated arguments object and
1448 // initialize the header in the elements fixed array. 1443 // initialize the header in the elements fixed array.
1449 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize)); 1444 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
1450 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 1445 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
1451 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 1446 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1452 Immediate(isolate->factory()->fixed_array_map())); 1447 Immediate(isolate()->factory()->fixed_array_map()));
1453 1448
1454 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); 1449 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1455 // Untag the length for the loop below. 1450 // Untag the length for the loop below.
1456 __ SmiUntag(ecx); 1451 __ SmiUntag(ecx);
1457 1452
1458 // Copy the fixed array slots. 1453 // Copy the fixed array slots.
1459 Label loop; 1454 Label loop;
1460 __ bind(&loop); 1455 __ bind(&loop);
1461 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. 1456 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
1462 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); 1457 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
(...skipping 26 matching lines...) Expand all
1489 // esp[8]: previous index 1484 // esp[8]: previous index
1490 // esp[12]: subject string 1485 // esp[12]: subject string
1491 // esp[16]: JSRegExp object 1486 // esp[16]: JSRegExp object
1492 1487
1493 static const int kLastMatchInfoOffset = 1 * kPointerSize; 1488 static const int kLastMatchInfoOffset = 1 * kPointerSize;
1494 static const int kPreviousIndexOffset = 2 * kPointerSize; 1489 static const int kPreviousIndexOffset = 2 * kPointerSize;
1495 static const int kSubjectOffset = 3 * kPointerSize; 1490 static const int kSubjectOffset = 3 * kPointerSize;
1496 static const int kJSRegExpOffset = 4 * kPointerSize; 1491 static const int kJSRegExpOffset = 4 * kPointerSize;
1497 1492
1498 Label runtime; 1493 Label runtime;
1499 Factory* factory = masm->isolate()->factory(); 1494 Factory* factory = isolate()->factory();
1500 1495
1501 // Ensure that a RegExp stack is allocated. 1496 // Ensure that a RegExp stack is allocated.
1502 ExternalReference address_of_regexp_stack_memory_address = 1497 ExternalReference address_of_regexp_stack_memory_address =
1503 ExternalReference::address_of_regexp_stack_memory_address( 1498 ExternalReference::address_of_regexp_stack_memory_address(isolate());
1504 masm->isolate());
1505 ExternalReference address_of_regexp_stack_memory_size = 1499 ExternalReference address_of_regexp_stack_memory_size =
1506 ExternalReference::address_of_regexp_stack_memory_size(masm->isolate()); 1500 ExternalReference::address_of_regexp_stack_memory_size(isolate());
1507 __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); 1501 __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
1508 __ test(ebx, ebx); 1502 __ test(ebx, ebx);
1509 __ j(zero, &runtime); 1503 __ j(zero, &runtime);
1510 1504
1511 // Check that the first argument is a JSRegExp object. 1505 // Check that the first argument is a JSRegExp object.
1512 __ mov(eax, Operand(esp, kJSRegExpOffset)); 1506 __ mov(eax, Operand(esp, kJSRegExpOffset));
1513 STATIC_ASSERT(kSmiTag == 0); 1507 STATIC_ASSERT(kSmiTag == 0);
1514 __ JumpIfSmi(eax, &runtime); 1508 __ JumpIfSmi(eax, &runtime);
1515 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); 1509 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
1516 __ j(not_equal, &runtime); 1510 __ j(not_equal, &runtime);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 // Check that the irregexp code has been generated for the actual string 1639 // Check that the irregexp code has been generated for the actual string
1646 // encoding. If it has, the field contains a code object otherwise it contains 1640 // encoding. If it has, the field contains a code object otherwise it contains
1647 // a smi (code flushing support). 1641 // a smi (code flushing support).
1648 __ JumpIfSmi(edx, &runtime); 1642 __ JumpIfSmi(edx, &runtime);
1649 1643
1650 // eax: subject string 1644 // eax: subject string
1651 // ebx: previous index (smi) 1645 // ebx: previous index (smi)
1652 // edx: code 1646 // edx: code
1653 // ecx: encoding of subject string (1 if ASCII, 0 if two_byte); 1647 // ecx: encoding of subject string (1 if ASCII, 0 if two_byte);
1654 // All checks done. Now push arguments for native regexp code. 1648 // All checks done. Now push arguments for native regexp code.
1655 Counters* counters = masm->isolate()->counters(); 1649 Counters* counters = isolate()->counters();
1656 __ IncrementCounter(counters->regexp_entry_native(), 1); 1650 __ IncrementCounter(counters->regexp_entry_native(), 1);
1657 1651
1658 // Isolates: note we add an additional parameter here (isolate pointer). 1652 // Isolates: note we add an additional parameter here (isolate pointer).
1659 static const int kRegExpExecuteArguments = 9; 1653 static const int kRegExpExecuteArguments = 9;
1660 __ EnterApiExitFrame(kRegExpExecuteArguments); 1654 __ EnterApiExitFrame(kRegExpExecuteArguments);
1661 1655
1662 // Argument 9: Pass current isolate address. 1656 // Argument 9: Pass current isolate address.
1663 __ mov(Operand(esp, 8 * kPointerSize), 1657 __ mov(Operand(esp, 8 * kPointerSize),
1664 Immediate(ExternalReference::isolate_address(masm->isolate()))); 1658 Immediate(ExternalReference::isolate_address(isolate())));
1665 1659
1666 // Argument 8: Indicate that this is a direct call from JavaScript. 1660 // Argument 8: Indicate that this is a direct call from JavaScript.
1667 __ mov(Operand(esp, 7 * kPointerSize), Immediate(1)); 1661 __ mov(Operand(esp, 7 * kPointerSize), Immediate(1));
1668 1662
1669 // Argument 7: Start (high end) of backtracking stack memory area. 1663 // Argument 7: Start (high end) of backtracking stack memory area.
1670 __ mov(esi, Operand::StaticVariable(address_of_regexp_stack_memory_address)); 1664 __ mov(esi, Operand::StaticVariable(address_of_regexp_stack_memory_address));
1671 __ add(esi, Operand::StaticVariable(address_of_regexp_stack_memory_size)); 1665 __ add(esi, Operand::StaticVariable(address_of_regexp_stack_memory_size));
1672 __ mov(Operand(esp, 6 * kPointerSize), esi); 1666 __ mov(Operand(esp, 6 * kPointerSize), esi);
1673 1667
1674 // Argument 6: Set the number of capture registers to zero to force global 1668 // Argument 6: Set the number of capture registers to zero to force global
1675 // regexps to behave as non-global. This does not affect non-global regexps. 1669 // regexps to behave as non-global. This does not affect non-global regexps.
1676 __ mov(Operand(esp, 5 * kPointerSize), Immediate(0)); 1670 __ mov(Operand(esp, 5 * kPointerSize), Immediate(0));
1677 1671
1678 // Argument 5: static offsets vector buffer. 1672 // Argument 5: static offsets vector buffer.
1679 __ mov(Operand(esp, 4 * kPointerSize), 1673 __ mov(Operand(esp, 4 * kPointerSize),
1680 Immediate(ExternalReference::address_of_static_offsets_vector( 1674 Immediate(ExternalReference::address_of_static_offsets_vector(
1681 masm->isolate()))); 1675 isolate())));
1682 1676
1683 // Argument 2: Previous index. 1677 // Argument 2: Previous index.
1684 __ SmiUntag(ebx); 1678 __ SmiUntag(ebx);
1685 __ mov(Operand(esp, 1 * kPointerSize), ebx); 1679 __ mov(Operand(esp, 1 * kPointerSize), ebx);
1686 1680
1687 // Argument 1: Original subject string. 1681 // Argument 1: Original subject string.
1688 // The original subject is in the previous stack frame. Therefore we have to 1682 // The original subject is in the previous stack frame. Therefore we have to
1689 // use ebp, which points exactly to one pointer size below the previous esp. 1683 // use ebp, which points exactly to one pointer size below the previous esp.
1690 // (Because creating a new stack frame pushes the previous ebp onto the stack 1684 // (Because creating a new stack frame pushes the previous ebp onto the stack
1691 // and thereby moves up esp by one kPointerSize.) 1685 // and thereby moves up esp by one kPointerSize.)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); 1739 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE);
1746 __ j(equal, &failure); 1740 __ j(equal, &failure);
1747 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); 1741 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION);
1748 // If not exception it can only be retry. Handle that in the runtime system. 1742 // If not exception it can only be retry. Handle that in the runtime system.
1749 __ j(not_equal, &runtime); 1743 __ j(not_equal, &runtime);
1750 // Result must now be exception. If there is no pending exception already a 1744 // Result must now be exception. If there is no pending exception already a
1751 // stack overflow (on the backtrack stack) was detected in RegExp code but 1745 // stack overflow (on the backtrack stack) was detected in RegExp code but
1752 // haven't created the exception yet. Handle that in the runtime system. 1746 // haven't created the exception yet. Handle that in the runtime system.
1753 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 1747 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
1754 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, 1748 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
1755 masm->isolate()); 1749 isolate());
1756 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 1750 __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
1757 __ mov(eax, Operand::StaticVariable(pending_exception)); 1751 __ mov(eax, Operand::StaticVariable(pending_exception));
1758 __ cmp(edx, eax); 1752 __ cmp(edx, eax);
1759 __ j(equal, &runtime); 1753 __ j(equal, &runtime);
1760 // For exception, throw the exception again. 1754 // For exception, throw the exception again.
1761 1755
1762 // Clear the pending exception variable. 1756 // Clear the pending exception variable.
1763 __ mov(Operand::StaticVariable(pending_exception), edx); 1757 __ mov(Operand::StaticVariable(pending_exception), edx);
1764 1758
1765 // Special handling of termination exceptions which are uncatchable 1759 // Special handling of termination exceptions which are uncatchable
1766 // by javascript code. 1760 // by javascript code.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 __ mov(eax, ecx); 1821 __ mov(eax, ecx);
1828 __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax); 1822 __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax);
1829 __ RecordWriteField(ebx, 1823 __ RecordWriteField(ebx,
1830 RegExpImpl::kLastInputOffset, 1824 RegExpImpl::kLastInputOffset,
1831 eax, 1825 eax,
1832 edi, 1826 edi,
1833 kDontSaveFPRegs); 1827 kDontSaveFPRegs);
1834 1828
1835 // Get the static offsets vector filled by the native regexp code. 1829 // Get the static offsets vector filled by the native regexp code.
1836 ExternalReference address_of_static_offsets_vector = 1830 ExternalReference address_of_static_offsets_vector =
1837 ExternalReference::address_of_static_offsets_vector(masm->isolate()); 1831 ExternalReference::address_of_static_offsets_vector(isolate());
1838 __ mov(ecx, Immediate(address_of_static_offsets_vector)); 1832 __ mov(ecx, Immediate(address_of_static_offsets_vector));
1839 1833
1840 // ebx: last_match_info backing store (FixedArray) 1834 // ebx: last_match_info backing store (FixedArray)
1841 // ecx: offsets vector 1835 // ecx: offsets vector
1842 // edx: number of capture registers 1836 // edx: number of capture registers
1843 Label next_capture, done; 1837 Label next_capture, done;
1844 // Capture register counter starts from number of capture registers and 1838 // Capture register counter starts from number of capture registers and
1845 // counts down until wraping after zero. 1839 // counts down until wraping after zero.
1846 __ bind(&next_capture); 1840 __ bind(&next_capture);
1847 __ sub(edx, Immediate(1)); 1841 __ sub(edx, Immediate(1));
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 Label generic_heap_number_comparison; 1987 Label generic_heap_number_comparison;
1994 { 1988 {
1995 Label not_identical; 1989 Label not_identical;
1996 __ cmp(eax, edx); 1990 __ cmp(eax, edx);
1997 __ j(not_equal, &not_identical); 1991 __ j(not_equal, &not_identical);
1998 1992
1999 if (cc != equal) { 1993 if (cc != equal) {
2000 // Check for undefined. undefined OP undefined is false even though 1994 // Check for undefined. undefined OP undefined is false even though
2001 // undefined == undefined. 1995 // undefined == undefined.
2002 Label check_for_nan; 1996 Label check_for_nan;
2003 __ cmp(edx, masm->isolate()->factory()->undefined_value()); 1997 __ cmp(edx, isolate()->factory()->undefined_value());
2004 __ j(not_equal, &check_for_nan, Label::kNear); 1998 __ j(not_equal, &check_for_nan, Label::kNear);
2005 __ Move(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 1999 __ Move(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
2006 __ ret(0); 2000 __ ret(0);
2007 __ bind(&check_for_nan); 2001 __ bind(&check_for_nan);
2008 } 2002 }
2009 2003
2010 // Test for NaN. Compare heap numbers in a general way, 2004 // Test for NaN. Compare heap numbers in a general way,
2011 // to hanlde NaNs correctly. 2005 // to hanlde NaNs correctly.
2012 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2006 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2013 Immediate(masm->isolate()->factory()->heap_number_map())); 2007 Immediate(isolate()->factory()->heap_number_map()));
2014 __ j(equal, &generic_heap_number_comparison, Label::kNear); 2008 __ j(equal, &generic_heap_number_comparison, Label::kNear);
2015 if (cc != equal) { 2009 if (cc != equal) {
2016 // Call runtime on identical JSObjects. Otherwise return equal. 2010 // Call runtime on identical JSObjects. Otherwise return equal.
2017 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 2011 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2018 __ j(above_equal, &not_identical); 2012 __ j(above_equal, &not_identical);
2019 } 2013 }
2020 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); 2014 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
2021 __ ret(0); 2015 __ ret(0);
2022 2016
2023 2017
(...skipping 24 matching lines...) Expand all
2048 // ecx still holds eax & kSmiTag, which is either zero or one. 2042 // ecx still holds eax & kSmiTag, which is either zero or one.
2049 __ sub(ecx, Immediate(0x01)); 2043 __ sub(ecx, Immediate(0x01));
2050 __ mov(ebx, edx); 2044 __ mov(ebx, edx);
2051 __ xor_(ebx, eax); 2045 __ xor_(ebx, eax);
2052 __ and_(ebx, ecx); // ebx holds either 0 or eax ^ edx. 2046 __ and_(ebx, ecx); // ebx holds either 0 or eax ^ edx.
2053 __ xor_(ebx, eax); 2047 __ xor_(ebx, eax);
2054 // if eax was smi, ebx is now edx, else eax. 2048 // if eax was smi, ebx is now edx, else eax.
2055 2049
2056 // Check if the non-smi operand is a heap number. 2050 // Check if the non-smi operand is a heap number.
2057 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 2051 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
2058 Immediate(masm->isolate()->factory()->heap_number_map())); 2052 Immediate(isolate()->factory()->heap_number_map()));
2059 // If heap number, handle it in the slow case. 2053 // If heap number, handle it in the slow case.
2060 __ j(equal, &slow, Label::kNear); 2054 __ j(equal, &slow, Label::kNear);
2061 // Return non-equal (ebx is not zero) 2055 // Return non-equal (ebx is not zero)
2062 __ mov(eax, ebx); 2056 __ mov(eax, ebx);
2063 __ ret(0); 2057 __ ret(0);
2064 2058
2065 __ bind(&not_smis); 2059 __ bind(&not_smis);
2066 // If either operand is a JSObject or an oddball value, then they are not 2060 // If either operand is a JSObject or an oddball value, then they are not
2067 // equal since their pointers are different 2061 // equal since their pointers are different
2068 // There is no test for undetectability in strict equality. 2062 // There is no test for undetectability in strict equality.
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2277 __ cmp(ecx, edi); 2271 __ cmp(ecx, edi);
2278 __ j(equal, &done, Label::kFar); 2272 __ j(equal, &done, Label::kFar);
2279 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); 2273 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
2280 __ j(equal, &done, Label::kFar); 2274 __ j(equal, &done, Label::kFar);
2281 2275
2282 if (!FLAG_pretenuring_call_new) { 2276 if (!FLAG_pretenuring_call_new) {
2283 // If we came here, we need to see if we are the array function. 2277 // If we came here, we need to see if we are the array function.
2284 // If we didn't have a matching function, and we didn't find the megamorph 2278 // If we didn't have a matching function, and we didn't find the megamorph
2285 // sentinel, then we have in the slot either some other function or an 2279 // sentinel, then we have in the slot either some other function or an
2286 // AllocationSite. Do a map check on the object in ecx. 2280 // AllocationSite. Do a map check on the object in ecx.
2287 Handle<Map> allocation_site_map = 2281 Handle<Map> allocation_site_map = isolate->factory()->allocation_site_map();
2288 masm->isolate()->factory()->allocation_site_map();
2289 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); 2282 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
2290 __ j(not_equal, &miss); 2283 __ j(not_equal, &miss);
2291 2284
2292 // Make sure the function is the Array() function 2285 // Make sure the function is the Array() function
2293 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); 2286 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
2294 __ cmp(edi, ecx); 2287 __ cmp(edi, ecx);
2295 __ j(not_equal, &megamorphic); 2288 __ j(not_equal, &megamorphic);
2296 __ jmp(&done, Label::kFar); 2289 __ jmp(&done, Label::kFar);
2297 } 2290 }
2298 2291
(...skipping 26 matching lines...) Expand all
2325 { 2318 {
2326 FrameScope scope(masm, StackFrame::INTERNAL); 2319 FrameScope scope(masm, StackFrame::INTERNAL);
2327 2320
2328 // Arguments register must be smi-tagged to call out. 2321 // Arguments register must be smi-tagged to call out.
2329 __ SmiTag(eax); 2322 __ SmiTag(eax);
2330 __ push(eax); 2323 __ push(eax);
2331 __ push(edi); 2324 __ push(edi);
2332 __ push(edx); 2325 __ push(edx);
2333 __ push(ebx); 2326 __ push(ebx);
2334 2327
2335 CreateAllocationSiteStub create_stub; 2328 CreateAllocationSiteStub create_stub(isolate);
2336 __ CallStub(&create_stub); 2329 __ CallStub(&create_stub);
2337 2330
2338 __ pop(ebx); 2331 __ pop(ebx);
2339 __ pop(edx); 2332 __ pop(edx);
2340 __ pop(edi); 2333 __ pop(edi);
2341 __ pop(eax); 2334 __ pop(eax);
2342 __ SmiUntag(eax); 2335 __ SmiUntag(eax);
2343 } 2336 }
2344 __ jmp(&done); 2337 __ jmp(&done);
2345 2338
(...skipping 15 matching lines...) Expand all
2361 2354
2362 __ bind(&done); 2355 __ bind(&done);
2363 } 2356 }
2364 2357
2365 2358
2366 void CallFunctionStub::Generate(MacroAssembler* masm) { 2359 void CallFunctionStub::Generate(MacroAssembler* masm) {
2367 // ebx : feedback vector 2360 // ebx : feedback vector
2368 // edx : (only if ebx is not the megamorphic symbol) slot in feedback 2361 // edx : (only if ebx is not the megamorphic symbol) slot in feedback
2369 // vector (Smi) 2362 // vector (Smi)
2370 // edi : the function to call 2363 // edi : the function to call
2371 Isolate* isolate = masm->isolate();
2372 Label slow, non_function, wrap, cont; 2364 Label slow, non_function, wrap, cont;
2373 2365
2374 if (NeedsChecks()) { 2366 if (NeedsChecks()) {
2375 // Check that the function really is a JavaScript function. 2367 // Check that the function really is a JavaScript function.
2376 __ JumpIfSmi(edi, &non_function); 2368 __ JumpIfSmi(edi, &non_function);
2377 2369
2378 // Goto slow case if we do not have a function. 2370 // Goto slow case if we do not have a function.
2379 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2371 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2380 __ j(not_equal, &slow); 2372 __ j(not_equal, &slow);
2381 2373
2382 if (RecordCallTarget()) { 2374 if (RecordCallTarget()) {
2383 GenerateRecordCallTarget(masm); 2375 GenerateRecordCallTarget(masm);
2384 // Type information was updated. Because we may call Array, which 2376 // Type information was updated. Because we may call Array, which
2385 // expects either undefined or an AllocationSite in ebx we need 2377 // expects either undefined or an AllocationSite in ebx we need
2386 // to set ebx to undefined. 2378 // to set ebx to undefined.
2387 __ mov(ebx, Immediate(isolate->factory()->undefined_value())); 2379 __ mov(ebx, Immediate(isolate()->factory()->undefined_value()));
2388 } 2380 }
2389 } 2381 }
2390 2382
2391 // Fast-case: Just invoke the function. 2383 // Fast-case: Just invoke the function.
2392 ParameterCount actual(argc_); 2384 ParameterCount actual(argc_);
2393 2385
2394 if (CallAsMethod()) { 2386 if (CallAsMethod()) {
2395 if (NeedsChecks()) { 2387 if (NeedsChecks()) {
2396 // Do not transform the receiver for strict mode functions. 2388 // Do not transform the receiver for strict mode functions.
2397 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 2389 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
(...skipping 26 matching lines...) Expand all
2424 2416
2425 if (NeedsChecks()) { 2417 if (NeedsChecks()) {
2426 // Slow-case: Non-function called. 2418 // Slow-case: Non-function called.
2427 __ bind(&slow); 2419 __ bind(&slow);
2428 if (RecordCallTarget()) { 2420 if (RecordCallTarget()) {
2429 // If there is a call target cache, mark it megamorphic in the 2421 // If there is a call target cache, mark it megamorphic in the
2430 // non-function case. MegamorphicSentinel is an immortal immovable 2422 // non-function case. MegamorphicSentinel is an immortal immovable
2431 // object (megamorphic symbol) so no write barrier is needed. 2423 // object (megamorphic symbol) so no write barrier is needed.
2432 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, 2424 __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
2433 FixedArray::kHeaderSize), 2425 FixedArray::kHeaderSize),
2434 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); 2426 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
2435 } 2427 }
2436 // Check for function proxy. 2428 // Check for function proxy.
2437 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); 2429 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
2438 __ j(not_equal, &non_function); 2430 __ j(not_equal, &non_function);
2439 __ pop(ecx); 2431 __ pop(ecx);
2440 __ push(edi); // put proxy as additional argument under return address 2432 __ push(edi); // put proxy as additional argument under return address
2441 __ push(ecx); 2433 __ push(ecx);
2442 __ Move(eax, Immediate(argc_ + 1)); 2434 __ Move(eax, Immediate(argc_ + 1));
2443 __ Move(ebx, Immediate(0)); 2435 __ Move(ebx, Immediate(0));
2444 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); 2436 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
2445 { 2437 {
2446 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); 2438 Handle<Code> adaptor =
2439 isolate()->builtins()->ArgumentsAdaptorTrampoline();
2447 __ jmp(adaptor, RelocInfo::CODE_TARGET); 2440 __ jmp(adaptor, RelocInfo::CODE_TARGET);
2448 } 2441 }
2449 2442
2450 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 2443 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
2451 // of the original receiver from the call site). 2444 // of the original receiver from the call site).
2452 __ bind(&non_function); 2445 __ bind(&non_function);
2453 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); 2446 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
2454 __ Move(eax, Immediate(argc_)); 2447 __ Move(eax, Immediate(argc_));
2455 __ Move(ebx, Immediate(0)); 2448 __ Move(ebx, Immediate(0));
2456 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 2449 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
2457 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); 2450 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
2458 __ jmp(adaptor, RelocInfo::CODE_TARGET); 2451 __ jmp(adaptor, RelocInfo::CODE_TARGET);
2459 } 2452 }
2460 2453
2461 if (CallAsMethod()) { 2454 if (CallAsMethod()) {
2462 __ bind(&wrap); 2455 __ bind(&wrap);
2463 // Wrap the receiver and patch it back onto the stack. 2456 // Wrap the receiver and patch it back onto the stack.
2464 { FrameScope frame_scope(masm, StackFrame::INTERNAL); 2457 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
2465 __ push(edi); 2458 __ push(edi);
2466 __ push(eax); 2459 __ push(eax);
2467 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 2460 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
(...skipping 27 matching lines...) Expand all
2495 // By adding kPointerSize we encode that we know the AllocationSite 2488 // By adding kPointerSize we encode that we know the AllocationSite
2496 // entry is at the feedback vector slot given by edx + 1. 2489 // entry is at the feedback vector slot given by edx + 1.
2497 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, 2490 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
2498 FixedArray::kHeaderSize + kPointerSize)); 2491 FixedArray::kHeaderSize + kPointerSize));
2499 } else { 2492 } else {
2500 Label feedback_register_initialized; 2493 Label feedback_register_initialized;
2501 // Put the AllocationSite from the feedback vector into ebx, or undefined. 2494 // Put the AllocationSite from the feedback vector into ebx, or undefined.
2502 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, 2495 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
2503 FixedArray::kHeaderSize)); 2496 FixedArray::kHeaderSize));
2504 Handle<Map> allocation_site_map = 2497 Handle<Map> allocation_site_map =
2505 masm->isolate()->factory()->allocation_site_map(); 2498 isolate()->factory()->allocation_site_map();
2506 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); 2499 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map));
2507 __ j(equal, &feedback_register_initialized); 2500 __ j(equal, &feedback_register_initialized);
2508 __ mov(ebx, masm->isolate()->factory()->undefined_value()); 2501 __ mov(ebx, isolate()->factory()->undefined_value());
2509 __ bind(&feedback_register_initialized); 2502 __ bind(&feedback_register_initialized);
2510 } 2503 }
2511 2504
2512 __ AssertUndefinedOrAllocationSite(ebx); 2505 __ AssertUndefinedOrAllocationSite(ebx);
2513 } 2506 }
2514 2507
2515 // Jump to the function-specific construct stub. 2508 // Jump to the function-specific construct stub.
2516 Register jmp_reg = ecx; 2509 Register jmp_reg = ecx;
2517 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 2510 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2518 __ mov(jmp_reg, FieldOperand(jmp_reg, 2511 __ mov(jmp_reg, FieldOperand(jmp_reg,
(...skipping 10 matching lines...) Expand all
2529 __ j(not_equal, &non_function_call); 2522 __ j(not_equal, &non_function_call);
2530 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 2523 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
2531 __ jmp(&do_call); 2524 __ jmp(&do_call);
2532 2525
2533 __ bind(&non_function_call); 2526 __ bind(&non_function_call);
2534 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 2527 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
2535 __ bind(&do_call); 2528 __ bind(&do_call);
2536 // Set expected number of arguments to zero (not changing eax). 2529 // Set expected number of arguments to zero (not changing eax).
2537 __ Move(ebx, Immediate(0)); 2530 __ Move(ebx, Immediate(0));
2538 Handle<Code> arguments_adaptor = 2531 Handle<Code> arguments_adaptor =
2539 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 2532 isolate()->builtins()->ArgumentsAdaptorTrampoline();
2540 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); 2533 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
2541 } 2534 }
2542 2535
2543 2536
2544 bool CEntryStub::NeedsImmovableCode() { 2537 bool CEntryStub::NeedsImmovableCode() {
2545 return false; 2538 return false;
2546 } 2539 }
2547 2540
2548 2541
2549 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 2542 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
2550 CEntryStub::GenerateAheadOfTime(isolate); 2543 CEntryStub::GenerateAheadOfTime(isolate);
2551 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 2544 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
2552 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 2545 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
2553 // It is important that the store buffer overflow stubs are generated first. 2546 // It is important that the store buffer overflow stubs are generated first.
2554 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 2547 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
2555 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); 2548 CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
2556 if (Serializer::enabled()) { 2549 if (Serializer::enabled()) {
2557 PlatformFeatureScope sse2(SSE2); 2550 PlatformFeatureScope sse2(SSE2);
2558 BinaryOpICStub::GenerateAheadOfTime(isolate); 2551 BinaryOpICStub::GenerateAheadOfTime(isolate);
2559 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); 2552 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2560 } else { 2553 } else {
2561 BinaryOpICStub::GenerateAheadOfTime(isolate); 2554 BinaryOpICStub::GenerateAheadOfTime(isolate);
2562 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); 2555 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2563 } 2556 }
2564 } 2557 }
2565 2558
2566 2559
2567 void CodeStub::GenerateFPStubs(Isolate* isolate) { 2560 void CodeStub::GenerateFPStubs(Isolate* isolate) {
2568 if (CpuFeatures::IsSupported(SSE2)) { 2561 if (CpuFeatures::IsSupported(SSE2)) {
2569 CEntryStub save_doubles(1, kSaveFPRegs); 2562 CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
2570 // Stubs might already be in the snapshot, detect that and don't regenerate, 2563 // Stubs might already be in the snapshot, detect that and don't regenerate,
2571 // which would lead to code stub initialization state being messed up. 2564 // which would lead to code stub initialization state being messed up.
2572 Code* save_doubles_code; 2565 Code* save_doubles_code;
2573 if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) { 2566 if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) {
2574 save_doubles_code = *(save_doubles.GetCode(isolate)); 2567 save_doubles_code = *(save_doubles.GetCode(isolate));
2575 } 2568 }
2576 isolate->set_fp_stubs_generated(true); 2569 isolate->set_fp_stubs_generated(true);
2577 } 2570 }
2578 } 2571 }
2579 2572
2580 2573
2581 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 2574 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
2582 CEntryStub stub(1, kDontSaveFPRegs); 2575 CEntryStub stub(isolate, 1, kDontSaveFPRegs);
2583 stub.GetCode(isolate); 2576 stub.GetCode(isolate);
2584 } 2577 }
2585 2578
2586 2579
2587 void CEntryStub::Generate(MacroAssembler* masm) { 2580 void CEntryStub::Generate(MacroAssembler* masm) {
2588 // eax: number of arguments including receiver 2581 // eax: number of arguments including receiver
2589 // ebx: pointer to C function (C callee-saved) 2582 // ebx: pointer to C function (C callee-saved)
2590 // ebp: frame pointer (restored after C call) 2583 // ebp: frame pointer (restored after C call)
2591 // esp: stack pointer (restored after C call) 2584 // esp: stack pointer (restored after C call)
2592 // esi: current context (C callee-saved) 2585 // esi: current context (C callee-saved)
2593 // edi: JS function of the caller (C callee-saved) 2586 // edi: JS function of the caller (C callee-saved)
2594 2587
2595 ProfileEntryHookStub::MaybeCallEntryHook(masm); 2588 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2596 2589
2597 // Enter the exit frame that transitions from JavaScript to C++. 2590 // Enter the exit frame that transitions from JavaScript to C++.
2598 __ EnterExitFrame(save_doubles_ == kSaveFPRegs); 2591 __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
2599 2592
2600 // ebx: pointer to C function (C callee-saved) 2593 // ebx: pointer to C function (C callee-saved)
2601 // ebp: frame pointer (restored after C call) 2594 // ebp: frame pointer (restored after C call)
2602 // esp: stack pointer (restored after C call) 2595 // esp: stack pointer (restored after C call)
2603 // edi: number of arguments including receiver (C callee-saved) 2596 // edi: number of arguments including receiver (C callee-saved)
2604 // esi: pointer to the first argument (C callee-saved) 2597 // esi: pointer to the first argument (C callee-saved)
2605 2598
2606 // Result returned in eax, or eax+edx if result_size_ is 2. 2599 // Result returned in eax, or eax+edx if result_size_ is 2.
2607 2600
2608 Isolate* isolate = masm->isolate();
2609
2610 // Check stack alignment. 2601 // Check stack alignment.
2611 if (FLAG_debug_code) { 2602 if (FLAG_debug_code) {
2612 __ CheckStackAlignment(); 2603 __ CheckStackAlignment();
2613 } 2604 }
2614 2605
2615 // Call C function. 2606 // Call C function.
2616 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. 2607 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
2617 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. 2608 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
2618 __ mov(Operand(esp, 2 * kPointerSize), 2609 __ mov(Operand(esp, 2 * kPointerSize),
2619 Immediate(ExternalReference::isolate_address(isolate))); 2610 Immediate(ExternalReference::isolate_address(isolate())));
2620 __ call(ebx); 2611 __ call(ebx);
2621 // Result is in eax or edx:eax - do not destroy these registers! 2612 // Result is in eax or edx:eax - do not destroy these registers!
2622 2613
2623 // Runtime functions should not return 'the hole'. Allowing it to escape may 2614 // Runtime functions should not return 'the hole'. Allowing it to escape may
2624 // lead to crashes in the IC code later. 2615 // lead to crashes in the IC code later.
2625 if (FLAG_debug_code) { 2616 if (FLAG_debug_code) {
2626 Label okay; 2617 Label okay;
2627 __ cmp(eax, isolate->factory()->the_hole_value()); 2618 __ cmp(eax, isolate()->factory()->the_hole_value());
2628 __ j(not_equal, &okay, Label::kNear); 2619 __ j(not_equal, &okay, Label::kNear);
2629 __ int3(); 2620 __ int3();
2630 __ bind(&okay); 2621 __ bind(&okay);
2631 } 2622 }
2632 2623
2633 // Check result for exception sentinel. 2624 // Check result for exception sentinel.
2634 Label exception_returned; 2625 Label exception_returned;
2635 __ cmp(eax, isolate->factory()->exception()); 2626 __ cmp(eax, isolate()->factory()->exception());
2636 __ j(equal, &exception_returned); 2627 __ j(equal, &exception_returned);
2637 2628
2638 ExternalReference pending_exception_address( 2629 ExternalReference pending_exception_address(
2639 Isolate::kPendingExceptionAddress, isolate); 2630 Isolate::kPendingExceptionAddress, isolate());
2640 2631
2641 // Check that there is no pending exception, otherwise we 2632 // Check that there is no pending exception, otherwise we
2642 // should have returned the exception sentinel. 2633 // should have returned the exception sentinel.
2643 if (FLAG_debug_code) { 2634 if (FLAG_debug_code) {
2644 __ push(edx); 2635 __ push(edx);
2645 __ mov(edx, Immediate(isolate->factory()->the_hole_value())); 2636 __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
2646 Label okay; 2637 Label okay;
2647 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); 2638 __ cmp(edx, Operand::StaticVariable(pending_exception_address));
2648 // Cannot use check here as it attempts to generate call into runtime. 2639 // Cannot use check here as it attempts to generate call into runtime.
2649 __ j(equal, &okay, Label::kNear); 2640 __ j(equal, &okay, Label::kNear);
2650 __ int3(); 2641 __ int3();
2651 __ bind(&okay); 2642 __ bind(&okay);
2652 __ pop(edx); 2643 __ pop(edx);
2653 } 2644 }
2654 2645
2655 // Exit the JavaScript to C++ exit frame. 2646 // Exit the JavaScript to C++ exit frame.
2656 __ LeaveExitFrame(save_doubles_ == kSaveFPRegs); 2647 __ LeaveExitFrame(save_doubles_ == kSaveFPRegs);
2657 __ ret(0); 2648 __ ret(0);
2658 2649
2659 // Handling of exception. 2650 // Handling of exception.
2660 __ bind(&exception_returned); 2651 __ bind(&exception_returned);
2661 2652
2662 // Retrieve the pending exception. 2653 // Retrieve the pending exception.
2663 __ mov(eax, Operand::StaticVariable(pending_exception_address)); 2654 __ mov(eax, Operand::StaticVariable(pending_exception_address));
2664 2655
2665 // Clear the pending exception. 2656 // Clear the pending exception.
2666 __ mov(edx, Immediate(isolate->factory()->the_hole_value())); 2657 __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
2667 __ mov(Operand::StaticVariable(pending_exception_address), edx); 2658 __ mov(Operand::StaticVariable(pending_exception_address), edx);
2668 2659
2669 // Special handling of termination exceptions which are uncatchable 2660 // Special handling of termination exceptions which are uncatchable
2670 // by javascript code. 2661 // by javascript code.
2671 Label throw_termination_exception; 2662 Label throw_termination_exception;
2672 __ cmp(eax, isolate->factory()->termination_exception()); 2663 __ cmp(eax, isolate()->factory()->termination_exception());
2673 __ j(equal, &throw_termination_exception); 2664 __ j(equal, &throw_termination_exception);
2674 2665
2675 // Handle normal exception. 2666 // Handle normal exception.
2676 __ Throw(eax); 2667 __ Throw(eax);
2677 2668
2678 __ bind(&throw_termination_exception); 2669 __ bind(&throw_termination_exception);
2679 __ ThrowUncatchable(eax); 2670 __ ThrowUncatchable(eax);
2680 } 2671 }
2681 2672
2682 2673
(...skipping 10 matching lines...) Expand all
2693 // Push marker in two places. 2684 // Push marker in two places.
2694 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 2685 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
2695 __ push(Immediate(Smi::FromInt(marker))); // context slot 2686 __ push(Immediate(Smi::FromInt(marker))); // context slot
2696 __ push(Immediate(Smi::FromInt(marker))); // function slot 2687 __ push(Immediate(Smi::FromInt(marker))); // function slot
2697 // Save callee-saved registers (C calling conventions). 2688 // Save callee-saved registers (C calling conventions).
2698 __ push(edi); 2689 __ push(edi);
2699 __ push(esi); 2690 __ push(esi);
2700 __ push(ebx); 2691 __ push(ebx);
2701 2692
2702 // Save copies of the top frame descriptor on the stack. 2693 // Save copies of the top frame descriptor on the stack.
2703 ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, masm->isolate()); 2694 ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, isolate());
2704 __ push(Operand::StaticVariable(c_entry_fp)); 2695 __ push(Operand::StaticVariable(c_entry_fp));
2705 2696
2706 // If this is the outermost JS call, set js_entry_sp value. 2697 // If this is the outermost JS call, set js_entry_sp value.
2707 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, 2698 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
2708 masm->isolate());
2709 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); 2699 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0));
2710 __ j(not_equal, &not_outermost_js, Label::kNear); 2700 __ j(not_equal, &not_outermost_js, Label::kNear);
2711 __ mov(Operand::StaticVariable(js_entry_sp), ebp); 2701 __ mov(Operand::StaticVariable(js_entry_sp), ebp);
2712 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); 2702 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
2713 __ jmp(&invoke, Label::kNear); 2703 __ jmp(&invoke, Label::kNear);
2714 __ bind(&not_outermost_js); 2704 __ bind(&not_outermost_js);
2715 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); 2705 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
2716 2706
2717 // Jump to a faked try block that does the invoke, with a faked catch 2707 // Jump to a faked try block that does the invoke, with a faked catch
2718 // block that sets the pending exception. 2708 // block that sets the pending exception.
2719 __ jmp(&invoke); 2709 __ jmp(&invoke);
2720 __ bind(&handler_entry); 2710 __ bind(&handler_entry);
2721 handler_offset_ = handler_entry.pos(); 2711 handler_offset_ = handler_entry.pos();
2722 // Caught exception: Store result (exception) in the pending exception 2712 // Caught exception: Store result (exception) in the pending exception
2723 // field in the JSEnv and return a failure sentinel. 2713 // field in the JSEnv and return a failure sentinel.
2724 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, 2714 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
2725 masm->isolate()); 2715 isolate());
2726 __ mov(Operand::StaticVariable(pending_exception), eax); 2716 __ mov(Operand::StaticVariable(pending_exception), eax);
2727 __ mov(eax, Immediate(masm->isolate()->factory()->exception())); 2717 __ mov(eax, Immediate(isolate()->factory()->exception()));
2728 __ jmp(&exit); 2718 __ jmp(&exit);
2729 2719
2730 // Invoke: Link this frame into the handler chain. There's only one 2720 // Invoke: Link this frame into the handler chain. There's only one
2731 // handler block in this code object, so its index is 0. 2721 // handler block in this code object, so its index is 0.
2732 __ bind(&invoke); 2722 __ bind(&invoke);
2733 __ PushTryHandler(StackHandler::JS_ENTRY, 0); 2723 __ PushTryHandler(StackHandler::JS_ENTRY, 0);
2734 2724
2735 // Clear any pending exceptions. 2725 // Clear any pending exceptions.
2736 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2726 __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
2737 __ mov(Operand::StaticVariable(pending_exception), edx); 2727 __ mov(Operand::StaticVariable(pending_exception), edx);
2738 2728
2739 // Fake a receiver (NULL). 2729 // Fake a receiver (NULL).
2740 __ push(Immediate(0)); // receiver 2730 __ push(Immediate(0)); // receiver
2741 2731
2742 // Invoke the function by calling through JS entry trampoline builtin and 2732 // Invoke the function by calling through JS entry trampoline builtin and
2743 // pop the faked function when we return. Notice that we cannot store a 2733 // pop the faked function when we return. Notice that we cannot store a
2744 // reference to the trampoline code directly in this stub, because the 2734 // reference to the trampoline code directly in this stub, because the
2745 // builtin stubs may not have been generated yet. 2735 // builtin stubs may not have been generated yet.
2746 if (is_construct) { 2736 if (is_construct) {
2747 ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, 2737 ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
2748 masm->isolate()); 2738 isolate());
2749 __ mov(edx, Immediate(construct_entry)); 2739 __ mov(edx, Immediate(construct_entry));
2750 } else { 2740 } else {
2751 ExternalReference entry(Builtins::kJSEntryTrampoline, 2741 ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
2752 masm->isolate());
2753 __ mov(edx, Immediate(entry)); 2742 __ mov(edx, Immediate(entry));
2754 } 2743 }
2755 __ mov(edx, Operand(edx, 0)); // deref address 2744 __ mov(edx, Operand(edx, 0)); // deref address
2756 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); 2745 __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
2757 __ call(edx); 2746 __ call(edx);
2758 2747
2759 // Unlink this frame from the handler chain. 2748 // Unlink this frame from the handler chain.
2760 __ PopTryHandler(); 2749 __ PopTryHandler();
2761 2750
2762 __ bind(&exit); 2751 __ bind(&exit);
2763 // Check if the current stack frame is marked as the outermost JS frame. 2752 // Check if the current stack frame is marked as the outermost JS frame.
2764 __ pop(ebx); 2753 __ pop(ebx);
2765 __ cmp(ebx, Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); 2754 __ cmp(ebx, Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
2766 __ j(not_equal, &not_outermost_js_2); 2755 __ j(not_equal, &not_outermost_js_2);
2767 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); 2756 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0));
2768 __ bind(&not_outermost_js_2); 2757 __ bind(&not_outermost_js_2);
2769 2758
2770 // Restore the top frame descriptor from the stack. 2759 // Restore the top frame descriptor from the stack.
2771 __ pop(Operand::StaticVariable(ExternalReference( 2760 __ pop(Operand::StaticVariable(ExternalReference(
2772 Isolate::kCEntryFPAddress, 2761 Isolate::kCEntryFPAddress, isolate())));
2773 masm->isolate())));
2774 2762
2775 // Restore callee-saved registers (C calling conventions). 2763 // Restore callee-saved registers (C calling conventions).
2776 __ pop(ebx); 2764 __ pop(ebx);
2777 __ pop(esi); 2765 __ pop(esi);
2778 __ pop(edi); 2766 __ pop(edi);
2779 __ add(esp, Immediate(2 * kPointerSize)); // remove markers 2767 __ add(esp, Immediate(2 * kPointerSize)); // remove markers
2780 2768
2781 // Restore frame pointer and return. 2769 // Restore frame pointer and return.
2782 __ pop(ebp); 2770 __ pop(ebp);
2783 __ ret(0); 2771 __ ret(0);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2876 __ mov(Operand(scratch, 0), map); 2864 __ mov(Operand(scratch, 0), map);
2877 } 2865 }
2878 2866
2879 // Loop through the prototype chain of the object looking for the function 2867 // Loop through the prototype chain of the object looking for the function
2880 // prototype. 2868 // prototype.
2881 __ mov(scratch, FieldOperand(map, Map::kPrototypeOffset)); 2869 __ mov(scratch, FieldOperand(map, Map::kPrototypeOffset));
2882 Label loop, is_instance, is_not_instance; 2870 Label loop, is_instance, is_not_instance;
2883 __ bind(&loop); 2871 __ bind(&loop);
2884 __ cmp(scratch, prototype); 2872 __ cmp(scratch, prototype);
2885 __ j(equal, &is_instance, Label::kNear); 2873 __ j(equal, &is_instance, Label::kNear);
2886 Factory* factory = masm->isolate()->factory(); 2874 Factory* factory = isolate()->factory();
2887 __ cmp(scratch, Immediate(factory->null_value())); 2875 __ cmp(scratch, Immediate(factory->null_value()));
2888 __ j(equal, &is_not_instance, Label::kNear); 2876 __ j(equal, &is_not_instance, Label::kNear);
2889 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 2877 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
2890 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); 2878 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
2891 __ jmp(&loop); 2879 __ jmp(&loop);
2892 2880
2893 __ bind(&is_instance); 2881 __ bind(&is_instance);
2894 if (!HasCallSiteInlineCheck()) { 2882 if (!HasCallSiteInlineCheck()) {
2895 __ mov(eax, Immediate(0)); 2883 __ mov(eax, Immediate(0));
2896 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); 2884 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
3288 __ mov(edx, Operand(esp, 2 * kPointerSize)); // From index. 3276 __ mov(edx, Operand(esp, 2 * kPointerSize)); // From index.
3289 __ JumpIfNotSmi(edx, &runtime); 3277 __ JumpIfNotSmi(edx, &runtime);
3290 __ sub(ecx, edx); 3278 __ sub(ecx, edx);
3291 __ cmp(ecx, FieldOperand(eax, String::kLengthOffset)); 3279 __ cmp(ecx, FieldOperand(eax, String::kLengthOffset));
3292 Label not_original_string; 3280 Label not_original_string;
3293 // Shorter than original string's length: an actual substring. 3281 // Shorter than original string's length: an actual substring.
3294 __ j(below, &not_original_string, Label::kNear); 3282 __ j(below, &not_original_string, Label::kNear);
3295 // Longer than original string's length or negative: unsafe arguments. 3283 // Longer than original string's length or negative: unsafe arguments.
3296 __ j(above, &runtime); 3284 __ j(above, &runtime);
3297 // Return original string. 3285 // Return original string.
3298 Counters* counters = masm->isolate()->counters(); 3286 Counters* counters = isolate()->counters();
3299 __ IncrementCounter(counters->sub_string_native(), 1); 3287 __ IncrementCounter(counters->sub_string_native(), 1);
3300 __ ret(3 * kPointerSize); 3288 __ ret(3 * kPointerSize);
3301 __ bind(&not_original_string); 3289 __ bind(&not_original_string);
3302 3290
3303 Label single_char; 3291 Label single_char;
3304 __ cmp(ecx, Immediate(Smi::FromInt(1))); 3292 __ cmp(ecx, Immediate(Smi::FromInt(1)));
3305 __ j(equal, &single_char); 3293 __ j(equal, &single_char);
3306 3294
3307 // eax: string 3295 // eax: string
3308 // ebx: instance type 3296 // ebx: instance type
3309 // ecx: sub string length (smi) 3297 // ecx: sub string length (smi)
3310 // edx: from index (smi) 3298 // edx: from index (smi)
3311 // Deal with different string types: update the index if necessary 3299 // Deal with different string types: update the index if necessary
3312 // and put the underlying string into edi. 3300 // and put the underlying string into edi.
3313 Label underlying_unpacked, sliced_string, seq_or_external_string; 3301 Label underlying_unpacked, sliced_string, seq_or_external_string;
3314 // If the string is not indirect, it can only be sequential or external. 3302 // If the string is not indirect, it can only be sequential or external.
3315 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag)); 3303 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
3316 STATIC_ASSERT(kIsIndirectStringMask != 0); 3304 STATIC_ASSERT(kIsIndirectStringMask != 0);
3317 __ test(ebx, Immediate(kIsIndirectStringMask)); 3305 __ test(ebx, Immediate(kIsIndirectStringMask));
3318 __ j(zero, &seq_or_external_string, Label::kNear); 3306 __ j(zero, &seq_or_external_string, Label::kNear);
3319 3307
3320 Factory* factory = masm->isolate()->factory(); 3308 Factory* factory = isolate()->factory();
3321 __ test(ebx, Immediate(kSlicedNotConsMask)); 3309 __ test(ebx, Immediate(kSlicedNotConsMask));
3322 __ j(not_zero, &sliced_string, Label::kNear); 3310 __ j(not_zero, &sliced_string, Label::kNear);
3323 // Cons string. Check whether it is flat, then fetch first part. 3311 // Cons string. Check whether it is flat, then fetch first part.
3324 // Flat cons strings have an empty second part. 3312 // Flat cons strings have an empty second part.
3325 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), 3313 __ cmp(FieldOperand(eax, ConsString::kSecondOffset),
3326 factory->empty_string()); 3314 factory->empty_string());
3327 __ j(not_equal, &runtime); 3315 __ j(not_equal, &runtime);
3328 __ mov(edi, FieldOperand(eax, ConsString::kFirstOffset)); 3316 __ mov(edi, FieldOperand(eax, ConsString::kFirstOffset));
3329 // Update instance type. 3317 // Update instance type.
3330 __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset)); 3318 __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset));
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
3630 3618
3631 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left 3619 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left
3632 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right 3620 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right
3633 3621
3634 Label not_same; 3622 Label not_same;
3635 __ cmp(edx, eax); 3623 __ cmp(edx, eax);
3636 __ j(not_equal, &not_same, Label::kNear); 3624 __ j(not_equal, &not_same, Label::kNear);
3637 STATIC_ASSERT(EQUAL == 0); 3625 STATIC_ASSERT(EQUAL == 0);
3638 STATIC_ASSERT(kSmiTag == 0); 3626 STATIC_ASSERT(kSmiTag == 0);
3639 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); 3627 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
3640 __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1); 3628 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1);
3641 __ ret(2 * kPointerSize); 3629 __ ret(2 * kPointerSize);
3642 3630
3643 __ bind(&not_same); 3631 __ bind(&not_same);
3644 3632
3645 // Check that both objects are sequential ASCII strings. 3633 // Check that both objects are sequential ASCII strings.
3646 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); 3634 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime);
3647 3635
3648 // Compare flat ASCII strings. 3636 // Compare flat ASCII strings.
3649 // Drop arguments from the stack. 3637 // Drop arguments from the stack.
3650 __ pop(ecx); 3638 __ pop(ecx);
3651 __ add(esp, Immediate(2 * kPointerSize)); 3639 __ add(esp, Immediate(2 * kPointerSize));
3652 __ push(ecx); 3640 __ push(ecx);
3653 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); 3641 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi);
3654 3642
3655 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 3643 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
3656 // tagged as a small integer. 3644 // tagged as a small integer.
3657 __ bind(&runtime); 3645 __ bind(&runtime);
3658 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); 3646 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1);
3659 } 3647 }
3660 3648
3661 3649
3662 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3650 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3663 // ----------- S t a t e ------------- 3651 // ----------- S t a t e -------------
3664 // -- edx : left 3652 // -- edx : left
3665 // -- eax : right 3653 // -- eax : right
3666 // -- esp[0] : return address 3654 // -- esp[0] : return address
3667 // ----------------------------------- 3655 // -----------------------------------
3668 Isolate* isolate = masm->isolate();
3669 3656
3670 // Load ecx with the allocation site. We stick an undefined dummy value here 3657 // Load ecx with the allocation site. We stick an undefined dummy value here
3671 // and replace it with the real allocation site later when we instantiate this 3658 // and replace it with the real allocation site later when we instantiate this
3672 // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate(). 3659 // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
3673 __ mov(ecx, handle(isolate->heap()->undefined_value())); 3660 __ mov(ecx, handle(isolate()->heap()->undefined_value()));
3674 3661
3675 // Make sure that we actually patched the allocation site. 3662 // Make sure that we actually patched the allocation site.
3676 if (FLAG_debug_code) { 3663 if (FLAG_debug_code) {
3677 __ test(ecx, Immediate(kSmiTagMask)); 3664 __ test(ecx, Immediate(kSmiTagMask));
3678 __ Assert(not_equal, kExpectedAllocationSite); 3665 __ Assert(not_equal, kExpectedAllocationSite);
3679 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 3666 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
3680 isolate->factory()->allocation_site_map()); 3667 isolate()->factory()->allocation_site_map());
3681 __ Assert(equal, kExpectedAllocationSite); 3668 __ Assert(equal, kExpectedAllocationSite);
3682 } 3669 }
3683 3670
3684 // Tail call into the stub that handles binary operations with allocation 3671 // Tail call into the stub that handles binary operations with allocation
3685 // sites. 3672 // sites.
3686 BinaryOpWithAllocationSiteStub stub(state_); 3673 BinaryOpWithAllocationSiteStub stub(isolate(), state_);
3687 __ TailCallStub(&stub); 3674 __ TailCallStub(&stub);
3688 } 3675 }
3689 3676
3690 3677
3691 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 3678 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
3692 ASSERT(state_ == CompareIC::SMI); 3679 ASSERT(state_ == CompareIC::SMI);
3693 Label miss; 3680 Label miss;
3694 __ mov(ecx, edx); 3681 __ mov(ecx, edx);
3695 __ or_(ecx, eax); 3682 __ or_(ecx, eax);
3696 __ JumpIfNotSmi(ecx, &miss, Label::kNear); 3683 __ JumpIfNotSmi(ecx, &miss, Label::kNear);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3731 // Inlining the double comparison and falling back to the general compare 3718 // Inlining the double comparison and falling back to the general compare
3732 // stub if NaN is involved or SSE2 or CMOV is unsupported. 3719 // stub if NaN is involved or SSE2 or CMOV is unsupported.
3733 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { 3720 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) {
3734 CpuFeatureScope scope1(masm, SSE2); 3721 CpuFeatureScope scope1(masm, SSE2);
3735 CpuFeatureScope scope2(masm, CMOV); 3722 CpuFeatureScope scope2(masm, CMOV);
3736 3723
3737 // Load left and right operand. 3724 // Load left and right operand.
3738 Label done, left, left_smi, right_smi; 3725 Label done, left, left_smi, right_smi;
3739 __ JumpIfSmi(eax, &right_smi, Label::kNear); 3726 __ JumpIfSmi(eax, &right_smi, Label::kNear);
3740 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3727 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3741 masm->isolate()->factory()->heap_number_map()); 3728 isolate()->factory()->heap_number_map());
3742 __ j(not_equal, &maybe_undefined1, Label::kNear); 3729 __ j(not_equal, &maybe_undefined1, Label::kNear);
3743 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 3730 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
3744 __ jmp(&left, Label::kNear); 3731 __ jmp(&left, Label::kNear);
3745 __ bind(&right_smi); 3732 __ bind(&right_smi);
3746 __ mov(ecx, eax); // Can't clobber eax because we can still jump away. 3733 __ mov(ecx, eax); // Can't clobber eax because we can still jump away.
3747 __ SmiUntag(ecx); 3734 __ SmiUntag(ecx);
3748 __ Cvtsi2sd(xmm1, ecx); 3735 __ Cvtsi2sd(xmm1, ecx);
3749 3736
3750 __ bind(&left); 3737 __ bind(&left);
3751 __ JumpIfSmi(edx, &left_smi, Label::kNear); 3738 __ JumpIfSmi(edx, &left_smi, Label::kNear);
3752 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 3739 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3753 masm->isolate()->factory()->heap_number_map()); 3740 isolate()->factory()->heap_number_map());
3754 __ j(not_equal, &maybe_undefined2, Label::kNear); 3741 __ j(not_equal, &maybe_undefined2, Label::kNear);
3755 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 3742 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
3756 __ jmp(&done); 3743 __ jmp(&done);
3757 __ bind(&left_smi); 3744 __ bind(&left_smi);
3758 __ mov(ecx, edx); // Can't clobber edx because we can still jump away. 3745 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
3759 __ SmiUntag(ecx); 3746 __ SmiUntag(ecx);
3760 __ Cvtsi2sd(xmm0, ecx); 3747 __ Cvtsi2sd(xmm0, ecx);
3761 3748
3762 __ bind(&done); 3749 __ bind(&done);
3763 // Compare operands. 3750 // Compare operands.
3764 __ ucomisd(xmm0, xmm1); 3751 __ ucomisd(xmm0, xmm1);
3765 3752
3766 // Don't base result on EFLAGS when a NaN is involved. 3753 // Don't base result on EFLAGS when a NaN is involved.
3767 __ j(parity_even, &unordered, Label::kNear); 3754 __ j(parity_even, &unordered, Label::kNear);
3768 3755
3769 // Return a result of -1, 0, or 1, based on EFLAGS. 3756 // Return a result of -1, 0, or 1, based on EFLAGS.
3770 // Performing mov, because xor would destroy the flag register. 3757 // Performing mov, because xor would destroy the flag register.
3771 __ mov(eax, 0); // equal 3758 __ mov(eax, 0); // equal
3772 __ mov(ecx, Immediate(Smi::FromInt(1))); 3759 __ mov(ecx, Immediate(Smi::FromInt(1)));
3773 __ cmov(above, eax, ecx); 3760 __ cmov(above, eax, ecx);
3774 __ mov(ecx, Immediate(Smi::FromInt(-1))); 3761 __ mov(ecx, Immediate(Smi::FromInt(-1)));
3775 __ cmov(below, eax, ecx); 3762 __ cmov(below, eax, ecx);
3776 __ ret(0); 3763 __ ret(0);
3777 } else { 3764 } else {
3778 __ mov(ecx, edx); 3765 __ mov(ecx, edx);
3779 __ and_(ecx, eax); 3766 __ and_(ecx, eax);
3780 __ JumpIfSmi(ecx, &generic_stub, Label::kNear); 3767 __ JumpIfSmi(ecx, &generic_stub, Label::kNear);
3781 3768
3782 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3769 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3783 masm->isolate()->factory()->heap_number_map()); 3770 isolate()->factory()->heap_number_map());
3784 __ j(not_equal, &maybe_undefined1, Label::kNear); 3771 __ j(not_equal, &maybe_undefined1, Label::kNear);
3785 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 3772 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3786 masm->isolate()->factory()->heap_number_map()); 3773 isolate()->factory()->heap_number_map());
3787 __ j(not_equal, &maybe_undefined2, Label::kNear); 3774 __ j(not_equal, &maybe_undefined2, Label::kNear);
3788 } 3775 }
3789 3776
3790 __ bind(&unordered); 3777 __ bind(&unordered);
3791 __ bind(&generic_stub); 3778 __ bind(&generic_stub);
3792 ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC, 3779 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
3793 CompareIC::GENERIC); 3780 CompareIC::GENERIC);
3794 __ jmp(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); 3781 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
3795 3782
3796 __ bind(&maybe_undefined1); 3783 __ bind(&maybe_undefined1);
3797 if (Token::IsOrderedRelationalCompareOp(op_)) { 3784 if (Token::IsOrderedRelationalCompareOp(op_)) {
3798 __ cmp(eax, Immediate(masm->isolate()->factory()->undefined_value())); 3785 __ cmp(eax, Immediate(isolate()->factory()->undefined_value()));
3799 __ j(not_equal, &miss); 3786 __ j(not_equal, &miss);
3800 __ JumpIfSmi(edx, &unordered); 3787 __ JumpIfSmi(edx, &unordered);
3801 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); 3788 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx);
3802 __ j(not_equal, &maybe_undefined2, Label::kNear); 3789 __ j(not_equal, &maybe_undefined2, Label::kNear);
3803 __ jmp(&unordered); 3790 __ jmp(&unordered);
3804 } 3791 }
3805 3792
3806 __ bind(&maybe_undefined2); 3793 __ bind(&maybe_undefined2);
3807 if (Token::IsOrderedRelationalCompareOp(op_)) { 3794 if (Token::IsOrderedRelationalCompareOp(op_)) {
3808 __ cmp(edx, Immediate(masm->isolate()->factory()->undefined_value())); 3795 __ cmp(edx, Immediate(isolate()->factory()->undefined_value()));
3809 __ j(equal, &unordered); 3796 __ j(equal, &unordered);
3810 } 3797 }
3811 3798
3812 __ bind(&miss); 3799 __ bind(&miss);
3813 GenerateMiss(masm); 3800 GenerateMiss(masm);
3814 } 3801 }
3815 3802
3816 3803
3817 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { 3804 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
3818 ASSERT(state_ == CompareIC::INTERNALIZED_STRING); 3805 ASSERT(state_ == CompareIC::INTERNALIZED_STRING);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
4033 4020
4034 __ bind(&miss); 4021 __ bind(&miss);
4035 GenerateMiss(masm); 4022 GenerateMiss(masm);
4036 } 4023 }
4037 4024
4038 4025
4039 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { 4026 void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
4040 { 4027 {
4041 // Call the runtime system in a fresh internal frame. 4028 // Call the runtime system in a fresh internal frame.
4042 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss), 4029 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss),
4043 masm->isolate()); 4030 isolate());
4044 FrameScope scope(masm, StackFrame::INTERNAL); 4031 FrameScope scope(masm, StackFrame::INTERNAL);
4045 __ push(edx); // Preserve edx and eax. 4032 __ push(edx); // Preserve edx and eax.
4046 __ push(eax); 4033 __ push(eax);
4047 __ push(edx); // And also use them as the arguments. 4034 __ push(edx); // And also use them as the arguments.
4048 __ push(eax); 4035 __ push(eax);
4049 __ push(Immediate(Smi::FromInt(op_))); 4036 __ push(Immediate(Smi::FromInt(op_)));
4050 __ CallExternalReference(miss, 3); 4037 __ CallExternalReference(miss, 3);
4051 // Compute the entry point of the rewritten stub. 4038 // Compute the entry point of the rewritten stub.
4052 __ lea(edi, FieldOperand(eax, Code::kHeaderSize)); 4039 __ lea(edi, FieldOperand(eax, Code::kHeaderSize));
4053 __ pop(eax); 4040 __ pop(eax);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4107 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value()); 4094 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value());
4108 __ j(equal, &good, Label::kNear); 4095 __ j(equal, &good, Label::kNear);
4109 4096
4110 // Check if the entry name is not a unique name. 4097 // Check if the entry name is not a unique name.
4111 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 4098 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
4112 __ JumpIfNotUniqueName(FieldOperand(entity_name, Map::kInstanceTypeOffset), 4099 __ JumpIfNotUniqueName(FieldOperand(entity_name, Map::kInstanceTypeOffset),
4113 miss); 4100 miss);
4114 __ bind(&good); 4101 __ bind(&good);
4115 } 4102 }
4116 4103
4117 NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP); 4104 NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0,
4105 NEGATIVE_LOOKUP);
4118 __ push(Immediate(Handle<Object>(name))); 4106 __ push(Immediate(Handle<Object>(name)));
4119 __ push(Immediate(name->Hash())); 4107 __ push(Immediate(name->Hash()));
4120 __ CallStub(&stub); 4108 __ CallStub(&stub);
4121 __ test(r0, r0); 4109 __ test(r0, r0);
4122 __ j(not_zero, miss); 4110 __ j(not_zero, miss);
4123 __ jmp(done); 4111 __ jmp(done);
4124 } 4112 }
4125 4113
4126 4114
4127 // Probe the name dictionary in the |elements| register. Jump to the 4115 // Probe the name dictionary in the |elements| register. Jump to the
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4163 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3 4151 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3
4164 4152
4165 // Check if the key is identical to the name. 4153 // Check if the key is identical to the name.
4166 __ cmp(name, Operand(elements, 4154 __ cmp(name, Operand(elements,
4167 r0, 4155 r0,
4168 times_4, 4156 times_4,
4169 kElementsStartOffset - kHeapObjectTag)); 4157 kElementsStartOffset - kHeapObjectTag));
4170 __ j(equal, done); 4158 __ j(equal, done);
4171 } 4159 }
4172 4160
4173 NameDictionaryLookupStub stub(elements, r1, r0, POSITIVE_LOOKUP); 4161 NameDictionaryLookupStub stub(masm->isolate(), elements, r1, r0,
4162 POSITIVE_LOOKUP);
4174 __ push(name); 4163 __ push(name);
4175 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); 4164 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset));
4176 __ shr(r0, Name::kHashShift); 4165 __ shr(r0, Name::kHashShift);
4177 __ push(r0); 4166 __ push(r0);
4178 __ CallStub(&stub); 4167 __ CallStub(&stub);
4179 4168
4180 __ test(r1, r1); 4169 __ test(r1, r1);
4181 __ j(zero, miss); 4170 __ j(zero, miss);
4182 __ jmp(done); 4171 __ jmp(done);
4183 } 4172 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4223 // Scale the index by multiplying by the entry size. 4212 // Scale the index by multiplying by the entry size.
4224 ASSERT(NameDictionary::kEntrySize == 3); 4213 ASSERT(NameDictionary::kEntrySize == 3);
4225 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3. 4214 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3.
4226 4215
4227 // Having undefined at this place means the name is not contained. 4216 // Having undefined at this place means the name is not contained.
4228 ASSERT_EQ(kSmiTagSize, 1); 4217 ASSERT_EQ(kSmiTagSize, 1);
4229 __ mov(scratch, Operand(dictionary_, 4218 __ mov(scratch, Operand(dictionary_,
4230 index_, 4219 index_,
4231 times_pointer_size, 4220 times_pointer_size,
4232 kElementsStartOffset - kHeapObjectTag)); 4221 kElementsStartOffset - kHeapObjectTag));
4233 __ cmp(scratch, masm->isolate()->factory()->undefined_value()); 4222 __ cmp(scratch, isolate()->factory()->undefined_value());
4234 __ j(equal, &not_in_dictionary); 4223 __ j(equal, &not_in_dictionary);
4235 4224
4236 // Stop if found the property. 4225 // Stop if found the property.
4237 __ cmp(scratch, Operand(esp, 3 * kPointerSize)); 4226 __ cmp(scratch, Operand(esp, 3 * kPointerSize));
4238 __ j(equal, &in_dictionary); 4227 __ j(equal, &in_dictionary);
4239 4228
4240 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 4229 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
4241 // If we hit a key that is not a unique name during negative 4230 // If we hit a key that is not a unique name during negative
4242 // lookup we have to bailout as this key might be equal to the 4231 // lookup we have to bailout as this key might be equal to the
4243 // key we are looking for. 4232 // key we are looking for.
(...skipping 22 matching lines...) Expand all
4266 4255
4267 __ bind(&not_in_dictionary); 4256 __ bind(&not_in_dictionary);
4268 __ mov(result_, Immediate(0)); 4257 __ mov(result_, Immediate(0));
4269 __ Drop(1); 4258 __ Drop(1);
4270 __ ret(2 * kPointerSize); 4259 __ ret(2 * kPointerSize);
4271 } 4260 }
4272 4261
4273 4262
4274 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( 4263 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
4275 Isolate* isolate) { 4264 Isolate* isolate) {
4276 StoreBufferOverflowStub stub(kDontSaveFPRegs); 4265 StoreBufferOverflowStub stub(isolate, kDontSaveFPRegs);
4277 stub.GetCode(isolate); 4266 stub.GetCode(isolate);
4278 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4267 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4279 StoreBufferOverflowStub stub2(kSaveFPRegs); 4268 StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
4280 stub2.GetCode(isolate); 4269 stub2.GetCode(isolate);
4281 } 4270 }
4282 } 4271 }
4283 4272
4284 4273
4285 bool CodeStub::CanUseFPRegisters() { 4274 bool CodeStub::CanUseFPRegisters() {
4286 return CpuFeatures::IsSupported(SSE2); 4275 return CpuFeatures::IsSupported(SSE2);
4287 } 4276 }
4288 4277
4289 4278
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 } 4358 }
4370 4359
4371 4360
4372 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { 4361 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
4373 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); 4362 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
4374 int argument_count = 3; 4363 int argument_count = 3;
4375 __ PrepareCallCFunction(argument_count, regs_.scratch0()); 4364 __ PrepareCallCFunction(argument_count, regs_.scratch0());
4376 __ mov(Operand(esp, 0 * kPointerSize), regs_.object()); 4365 __ mov(Operand(esp, 0 * kPointerSize), regs_.object());
4377 __ mov(Operand(esp, 1 * kPointerSize), regs_.address()); // Slot. 4366 __ mov(Operand(esp, 1 * kPointerSize), regs_.address()); // Slot.
4378 __ mov(Operand(esp, 2 * kPointerSize), 4367 __ mov(Operand(esp, 2 * kPointerSize),
4379 Immediate(ExternalReference::isolate_address(masm->isolate()))); 4368 Immediate(ExternalReference::isolate_address(isolate())));
4380 4369
4381 AllowExternalCallThatCantCauseGC scope(masm); 4370 AllowExternalCallThatCantCauseGC scope(masm);
4382 __ CallCFunction( 4371 __ CallCFunction(
4383 ExternalReference::incremental_marking_record_write_function( 4372 ExternalReference::incremental_marking_record_write_function(isolate()),
4384 masm->isolate()),
4385 argument_count); 4373 argument_count);
4386 4374
4387 regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_); 4375 regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
4388 } 4376 }
4389 4377
4390 4378
4391 void RecordWriteStub::CheckNeedsToInformIncrementalMarker( 4379 void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
4392 MacroAssembler* masm, 4380 MacroAssembler* masm,
4393 OnNoNeedToInformIncrementalMarker on_no_need, 4381 OnNoNeedToInformIncrementalMarker on_no_need,
4394 Mode mode) { 4382 Mode mode) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4561 edi, 4549 edi,
4562 xmm0, 4550 xmm0,
4563 &slow_elements_from_double, 4551 &slow_elements_from_double,
4564 false); 4552 false);
4565 __ pop(edx); 4553 __ pop(edx);
4566 __ ret(0); 4554 __ ret(0);
4567 } 4555 }
4568 4556
4569 4557
4570 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { 4558 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
4571 CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs); 4559 CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
4572 __ call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); 4560 __ call(ces.GetCode(isolate()), RelocInfo::CODE_TARGET);
4573 int parameter_count_offset = 4561 int parameter_count_offset =
4574 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; 4562 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
4575 __ mov(ebx, MemOperand(ebp, parameter_count_offset)); 4563 __ mov(ebx, MemOperand(ebp, parameter_count_offset));
4576 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); 4564 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4577 __ pop(ecx); 4565 __ pop(ecx);
4578 int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE 4566 int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE
4579 ? kPointerSize 4567 ? kPointerSize
4580 : 0; 4568 : 0;
4581 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); 4569 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset));
4582 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. 4570 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack.
4583 } 4571 }
4584 4572
4585 4573
4586 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4574 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4587 if (masm->isolate()->function_entry_hook() != NULL) { 4575 if (masm->isolate()->function_entry_hook() != NULL) {
4588 ProfileEntryHookStub stub; 4576 ProfileEntryHookStub stub(masm->isolate());
4589 masm->CallStub(&stub); 4577 masm->CallStub(&stub);
4590 } 4578 }
4591 } 4579 }
4592 4580
4593 4581
4594 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { 4582 void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
4595 // Save volatile registers. 4583 // Save volatile registers.
4596 const int kNumSavedRegisters = 3; 4584 const int kNumSavedRegisters = 3;
4597 __ push(eax); 4585 __ push(eax);
4598 __ push(ecx); 4586 __ push(ecx);
4599 __ push(edx); 4587 __ push(edx);
4600 4588
4601 // Calculate and push the original stack pointer. 4589 // Calculate and push the original stack pointer.
4602 __ lea(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize)); 4590 __ lea(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize));
4603 __ push(eax); 4591 __ push(eax);
4604 4592
4605 // Retrieve our return address and use it to calculate the calling 4593 // Retrieve our return address and use it to calculate the calling
4606 // function's address. 4594 // function's address.
4607 __ mov(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize)); 4595 __ mov(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize));
4608 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); 4596 __ sub(eax, Immediate(Assembler::kCallInstructionLength));
4609 __ push(eax); 4597 __ push(eax);
4610 4598
4611 // Call the entry hook. 4599 // Call the entry hook.
4612 ASSERT(masm->isolate()->function_entry_hook() != NULL); 4600 ASSERT(isolate()->function_entry_hook() != NULL);
4613 __ call(FUNCTION_ADDR(masm->isolate()->function_entry_hook()), 4601 __ call(FUNCTION_ADDR(isolate()->function_entry_hook()),
4614 RelocInfo::RUNTIME_ENTRY); 4602 RelocInfo::RUNTIME_ENTRY);
4615 __ add(esp, Immediate(2 * kPointerSize)); 4603 __ add(esp, Immediate(2 * kPointerSize));
4616 4604
4617 // Restore ecx. 4605 // Restore ecx.
4618 __ pop(edx); 4606 __ pop(edx);
4619 __ pop(ecx); 4607 __ pop(ecx);
4620 __ pop(eax); 4608 __ pop(eax);
4621 4609
4622 __ ret(0); 4610 __ ret(0);
4623 } 4611 }
4624 4612
4625 4613
4626 template<class T> 4614 template<class T>
4627 static void CreateArrayDispatch(MacroAssembler* masm, 4615 static void CreateArrayDispatch(MacroAssembler* masm,
4628 AllocationSiteOverrideMode mode) { 4616 AllocationSiteOverrideMode mode) {
4629 if (mode == DISABLE_ALLOCATION_SITES) { 4617 if (mode == DISABLE_ALLOCATION_SITES) {
4630 T stub(GetInitialFastElementsKind(), 4618 T stub(masm->isolate(),
4619 GetInitialFastElementsKind(),
4631 mode); 4620 mode);
4632 __ TailCallStub(&stub); 4621 __ TailCallStub(&stub);
4633 } else if (mode == DONT_OVERRIDE) { 4622 } else if (mode == DONT_OVERRIDE) {
4634 int last_index = GetSequenceIndexFromFastElementsKind( 4623 int last_index = GetSequenceIndexFromFastElementsKind(
4635 TERMINAL_FAST_ELEMENTS_KIND); 4624 TERMINAL_FAST_ELEMENTS_KIND);
4636 for (int i = 0; i <= last_index; ++i) { 4625 for (int i = 0; i <= last_index; ++i) {
4637 Label next; 4626 Label next;
4638 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4627 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4639 __ cmp(edx, kind); 4628 __ cmp(edx, kind);
4640 __ j(not_equal, &next); 4629 __ j(not_equal, &next);
4641 T stub(kind); 4630 T stub(masm->isolate(), kind);
4642 __ TailCallStub(&stub); 4631 __ TailCallStub(&stub);
4643 __ bind(&next); 4632 __ bind(&next);
4644 } 4633 }
4645 4634
4646 // If we reached this point there is a problem. 4635 // If we reached this point there is a problem.
4647 __ Abort(kUnexpectedElementsKindInArrayConstructor); 4636 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4648 } else { 4637 } else {
4649 UNREACHABLE(); 4638 UNREACHABLE();
4650 } 4639 }
4651 } 4640 }
(...skipping 23 matching lines...) Expand all
4675 4664
4676 // look at the first argument 4665 // look at the first argument
4677 __ mov(ecx, Operand(esp, kPointerSize)); 4666 __ mov(ecx, Operand(esp, kPointerSize));
4678 __ test(ecx, ecx); 4667 __ test(ecx, ecx);
4679 __ j(zero, &normal_sequence); 4668 __ j(zero, &normal_sequence);
4680 4669
4681 if (mode == DISABLE_ALLOCATION_SITES) { 4670 if (mode == DISABLE_ALLOCATION_SITES) {
4682 ElementsKind initial = GetInitialFastElementsKind(); 4671 ElementsKind initial = GetInitialFastElementsKind();
4683 ElementsKind holey_initial = GetHoleyElementsKind(initial); 4672 ElementsKind holey_initial = GetHoleyElementsKind(initial);
4684 4673
4685 ArraySingleArgumentConstructorStub stub_holey(holey_initial, 4674 ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
4675 holey_initial,
4686 DISABLE_ALLOCATION_SITES); 4676 DISABLE_ALLOCATION_SITES);
4687 __ TailCallStub(&stub_holey); 4677 __ TailCallStub(&stub_holey);
4688 4678
4689 __ bind(&normal_sequence); 4679 __ bind(&normal_sequence);
4690 ArraySingleArgumentConstructorStub stub(initial, 4680 ArraySingleArgumentConstructorStub stub(masm->isolate(),
4681 initial,
4691 DISABLE_ALLOCATION_SITES); 4682 DISABLE_ALLOCATION_SITES);
4692 __ TailCallStub(&stub); 4683 __ TailCallStub(&stub);
4693 } else if (mode == DONT_OVERRIDE) { 4684 } else if (mode == DONT_OVERRIDE) {
4694 // We are going to create a holey array, but our kind is non-holey. 4685 // We are going to create a holey array, but our kind is non-holey.
4695 // Fix kind and retry. 4686 // Fix kind and retry.
4696 __ inc(edx); 4687 __ inc(edx);
4697 4688
4698 if (FLAG_debug_code) { 4689 if (FLAG_debug_code) {
4699 Handle<Map> allocation_site_map = 4690 Handle<Map> allocation_site_map =
4700 masm->isolate()->factory()->allocation_site_map(); 4691 masm->isolate()->factory()->allocation_site_map();
4701 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); 4692 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map));
4702 __ Assert(equal, kExpectedAllocationSite); 4693 __ Assert(equal, kExpectedAllocationSite);
4703 } 4694 }
4704 4695
4705 // Save the resulting elements kind in type info. We can't just store r3 4696 // Save the resulting elements kind in type info. We can't just store r3
4706 // in the AllocationSite::transition_info field because elements kind is 4697 // in the AllocationSite::transition_info field because elements kind is
4707 // restricted to a portion of the field...upper bits need to be left alone. 4698 // restricted to a portion of the field...upper bits need to be left alone.
4708 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 4699 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
4709 __ add(FieldOperand(ebx, AllocationSite::kTransitionInfoOffset), 4700 __ add(FieldOperand(ebx, AllocationSite::kTransitionInfoOffset),
4710 Immediate(Smi::FromInt(kFastElementsKindPackedToHoley))); 4701 Immediate(Smi::FromInt(kFastElementsKindPackedToHoley)));
4711 4702
4712 __ bind(&normal_sequence); 4703 __ bind(&normal_sequence);
4713 int last_index = GetSequenceIndexFromFastElementsKind( 4704 int last_index = GetSequenceIndexFromFastElementsKind(
4714 TERMINAL_FAST_ELEMENTS_KIND); 4705 TERMINAL_FAST_ELEMENTS_KIND);
4715 for (int i = 0; i <= last_index; ++i) { 4706 for (int i = 0; i <= last_index; ++i) {
4716 Label next; 4707 Label next;
4717 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4708 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4718 __ cmp(edx, kind); 4709 __ cmp(edx, kind);
4719 __ j(not_equal, &next); 4710 __ j(not_equal, &next);
4720 ArraySingleArgumentConstructorStub stub(kind); 4711 ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
4721 __ TailCallStub(&stub); 4712 __ TailCallStub(&stub);
4722 __ bind(&next); 4713 __ bind(&next);
4723 } 4714 }
4724 4715
4725 // If we reached this point there is a problem. 4716 // If we reached this point there is a problem.
4726 __ Abort(kUnexpectedElementsKindInArrayConstructor); 4717 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4727 } else { 4718 } else {
4728 UNREACHABLE(); 4719 UNREACHABLE();
4729 } 4720 }
4730 } 4721 }
4731 4722
4732 4723
4733 template<class T> 4724 template<class T>
4734 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { 4725 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
4735 int to_index = GetSequenceIndexFromFastElementsKind( 4726 int to_index = GetSequenceIndexFromFastElementsKind(
4736 TERMINAL_FAST_ELEMENTS_KIND); 4727 TERMINAL_FAST_ELEMENTS_KIND);
4737 for (int i = 0; i <= to_index; ++i) { 4728 for (int i = 0; i <= to_index; ++i) {
4738 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4729 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4739 T stub(kind); 4730 T stub(isolate, kind);
4740 stub.GetCode(isolate); 4731 stub.GetCode(isolate);
4741 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { 4732 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
4742 T stub1(kind, DISABLE_ALLOCATION_SITES); 4733 T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
4743 stub1.GetCode(isolate); 4734 stub1.GetCode(isolate);
4744 } 4735 }
4745 } 4736 }
4746 } 4737 }
4747 4738
4748 4739
4749 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 4740 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
4750 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 4741 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
4751 isolate); 4742 isolate);
4752 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( 4743 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
4753 isolate); 4744 isolate);
4754 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( 4745 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
4755 isolate); 4746 isolate);
4756 } 4747 }
4757 4748
4758 4749
4759 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime( 4750 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
4760 Isolate* isolate) { 4751 Isolate* isolate) {
4761 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS }; 4752 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
4762 for (int i = 0; i < 2; i++) { 4753 for (int i = 0; i < 2; i++) {
4763 // For internal arrays we only need a few things 4754 // For internal arrays we only need a few things
4764 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); 4755 InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
4765 stubh1.GetCode(isolate); 4756 stubh1.GetCode(isolate);
4766 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); 4757 InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
4767 stubh2.GetCode(isolate); 4758 stubh2.GetCode(isolate);
4768 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); 4759 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
4769 stubh3.GetCode(isolate); 4760 stubh3.GetCode(isolate);
4770 } 4761 }
4771 } 4762 }
4772 4763
4773 4764
4774 void ArrayConstructorStub::GenerateDispatchToArrayStub( 4765 void ArrayConstructorStub::GenerateDispatchToArrayStub(
4775 MacroAssembler* masm, 4766 MacroAssembler* masm,
4776 AllocationSiteOverrideMode mode) { 4767 AllocationSiteOverrideMode mode) {
4777 if (argument_count_ == ANY) { 4768 if (argument_count_ == ANY) {
4778 Label not_zero_case, not_one_case; 4769 Label not_zero_case, not_one_case;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4819 __ CmpObjectType(ecx, MAP_TYPE, ecx); 4810 __ CmpObjectType(ecx, MAP_TYPE, ecx);
4820 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); 4811 __ Assert(equal, kUnexpectedInitialMapForArrayFunction);
4821 4812
4822 // We should either have undefined in ebx or a valid AllocationSite 4813 // We should either have undefined in ebx or a valid AllocationSite
4823 __ AssertUndefinedOrAllocationSite(ebx); 4814 __ AssertUndefinedOrAllocationSite(ebx);
4824 } 4815 }
4825 4816
4826 Label no_info; 4817 Label no_info;
4827 // If the feedback vector is the undefined value call an array constructor 4818 // If the feedback vector is the undefined value call an array constructor
4828 // that doesn't use AllocationSites. 4819 // that doesn't use AllocationSites.
4829 __ cmp(ebx, masm->isolate()->factory()->undefined_value()); 4820 __ cmp(ebx, isolate()->factory()->undefined_value());
4830 __ j(equal, &no_info); 4821 __ j(equal, &no_info);
4831 4822
4832 // Only look at the lower 16 bits of the transition info. 4823 // Only look at the lower 16 bits of the transition info.
4833 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); 4824 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset));
4834 __ SmiUntag(edx); 4825 __ SmiUntag(edx);
4835 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 4826 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
4836 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); 4827 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask));
4837 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); 4828 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
4838 4829
4839 __ bind(&no_info); 4830 __ bind(&no_info);
4840 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); 4831 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
4841 } 4832 }
4842 4833
4843 4834
4844 void InternalArrayConstructorStub::GenerateCase( 4835 void InternalArrayConstructorStub::GenerateCase(
4845 MacroAssembler* masm, ElementsKind kind) { 4836 MacroAssembler* masm, ElementsKind kind) {
4846 Label not_zero_case, not_one_case; 4837 Label not_zero_case, not_one_case;
4847 Label normal_sequence; 4838 Label normal_sequence;
4848 4839
4849 __ test(eax, eax); 4840 __ test(eax, eax);
4850 __ j(not_zero, &not_zero_case); 4841 __ j(not_zero, &not_zero_case);
4851 InternalArrayNoArgumentConstructorStub stub0(kind); 4842 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
4852 __ TailCallStub(&stub0); 4843 __ TailCallStub(&stub0);
4853 4844
4854 __ bind(&not_zero_case); 4845 __ bind(&not_zero_case);
4855 __ cmp(eax, 1); 4846 __ cmp(eax, 1);
4856 __ j(greater, &not_one_case); 4847 __ j(greater, &not_one_case);
4857 4848
4858 if (IsFastPackedElementsKind(kind)) { 4849 if (IsFastPackedElementsKind(kind)) {
4859 // We might need to create a holey array 4850 // We might need to create a holey array
4860 // look at the first argument 4851 // look at the first argument
4861 __ mov(ecx, Operand(esp, kPointerSize)); 4852 __ mov(ecx, Operand(esp, kPointerSize));
4862 __ test(ecx, ecx); 4853 __ test(ecx, ecx);
4863 __ j(zero, &normal_sequence); 4854 __ j(zero, &normal_sequence);
4864 4855
4865 InternalArraySingleArgumentConstructorStub 4856 InternalArraySingleArgumentConstructorStub
4866 stub1_holey(GetHoleyElementsKind(kind)); 4857 stub1_holey(isolate(), GetHoleyElementsKind(kind));
4867 __ TailCallStub(&stub1_holey); 4858 __ TailCallStub(&stub1_holey);
4868 } 4859 }
4869 4860
4870 __ bind(&normal_sequence); 4861 __ bind(&normal_sequence);
4871 InternalArraySingleArgumentConstructorStub stub1(kind); 4862 InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
4872 __ TailCallStub(&stub1); 4863 __ TailCallStub(&stub1);
4873 4864
4874 __ bind(&not_one_case); 4865 __ bind(&not_one_case);
4875 InternalArrayNArgumentsConstructorStub stubN(kind); 4866 InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
4876 __ TailCallStub(&stubN); 4867 __ TailCallStub(&stubN);
4877 } 4868 }
4878 4869
4879 4870
4880 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { 4871 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
4881 // ----------- S t a t e ------------- 4872 // ----------- S t a t e -------------
4882 // -- eax : argc 4873 // -- eax : argc
4883 // -- edi : constructor 4874 // -- edi : constructor
4884 // -- esp[0] : return address 4875 // -- esp[0] : return address
4885 // -- esp[4] : last argument 4876 // -- esp[4] : last argument
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4958 4949
4959 STATIC_ASSERT(FCA::kContextSaveIndex == 6); 4950 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
4960 STATIC_ASSERT(FCA::kCalleeIndex == 5); 4951 STATIC_ASSERT(FCA::kCalleeIndex == 5);
4961 STATIC_ASSERT(FCA::kDataIndex == 4); 4952 STATIC_ASSERT(FCA::kDataIndex == 4);
4962 STATIC_ASSERT(FCA::kReturnValueOffset == 3); 4953 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
4963 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); 4954 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
4964 STATIC_ASSERT(FCA::kIsolateIndex == 1); 4955 STATIC_ASSERT(FCA::kIsolateIndex == 1);
4965 STATIC_ASSERT(FCA::kHolderIndex == 0); 4956 STATIC_ASSERT(FCA::kHolderIndex == 0);
4966 STATIC_ASSERT(FCA::kArgsLength == 7); 4957 STATIC_ASSERT(FCA::kArgsLength == 7);
4967 4958
4968 Isolate* isolate = masm->isolate();
4969
4970 __ pop(return_address); 4959 __ pop(return_address);
4971 4960
4972 // context save 4961 // context save
4973 __ push(context); 4962 __ push(context);
4974 // load context from callee 4963 // load context from callee
4975 __ mov(context, FieldOperand(callee, JSFunction::kContextOffset)); 4964 __ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
4976 4965
4977 // callee 4966 // callee
4978 __ push(callee); 4967 __ push(callee);
4979 4968
4980 // call data 4969 // call data
4981 __ push(call_data); 4970 __ push(call_data);
4982 4971
4983 Register scratch = call_data; 4972 Register scratch = call_data;
4984 if (!call_data_undefined) { 4973 if (!call_data_undefined) {
4985 // return value 4974 // return value
4986 __ push(Immediate(isolate->factory()->undefined_value())); 4975 __ push(Immediate(isolate()->factory()->undefined_value()));
4987 // return value default 4976 // return value default
4988 __ push(Immediate(isolate->factory()->undefined_value())); 4977 __ push(Immediate(isolate()->factory()->undefined_value()));
4989 } else { 4978 } else {
4990 // return value 4979 // return value
4991 __ push(scratch); 4980 __ push(scratch);
4992 // return value default 4981 // return value default
4993 __ push(scratch); 4982 __ push(scratch);
4994 } 4983 }
4995 // isolate 4984 // isolate
4996 __ push(Immediate(reinterpret_cast<int>(isolate))); 4985 __ push(Immediate(reinterpret_cast<int>(isolate())));
4997 // holder 4986 // holder
4998 __ push(holder); 4987 __ push(holder);
4999 4988
5000 __ mov(scratch, esp); 4989 __ mov(scratch, esp);
5001 4990
5002 // return address 4991 // return address
5003 __ push(return_address); 4992 __ push(return_address);
5004 4993
5005 // API function gets reference to the v8::Arguments. If CPU profiler 4994 // API function gets reference to the v8::Arguments. If CPU profiler
5006 // is enabled wrapper function will be called and we need to pass 4995 // is enabled wrapper function will be called and we need to pass
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5085 Operand(ebp, 7 * kPointerSize), 5074 Operand(ebp, 7 * kPointerSize),
5086 NULL); 5075 NULL);
5087 } 5076 }
5088 5077
5089 5078
5090 #undef __ 5079 #undef __
5091 5080
5092 } } // namespace v8::internal 5081 } } // namespace v8::internal
5093 5082
5094 #endif // V8_TARGET_ARCH_IA32 5083 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698