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

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

Issue 21123008: Introduce StackArgumentsAccessor class for X64 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // Create a new closure from the given function info in new 310 // Create a new closure from the given function info in new
311 // space. Set the context to the current context in rsi. 311 // space. Set the context to the current context in rsi.
312 Counters* counters = masm->isolate()->counters(); 312 Counters* counters = masm->isolate()->counters();
313 313
314 Label gc; 314 Label gc;
315 __ Allocate(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT); 315 __ Allocate(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
316 316
317 __ IncrementCounter(counters->fast_new_closure_total(), 1); 317 __ IncrementCounter(counters->fast_new_closure_total(), 1);
318 318
319 // Get the function info from the stack. 319 // Get the function info from the stack.
320 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); 320 __ movq(rdx, StackOperandForArgument(1 * kPointerSize));
321 321
322 int map_index = Context::FunctionMapIndex(language_mode_, is_generator_); 322 int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
323 323
324 // Compute the function map in the current native context and set that 324 // Compute the function map in the current native context and set that
325 // as the map of the allocated object. 325 // as the map of the allocated object.
326 __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 326 __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
327 __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset)); 327 __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
328 __ movq(rbx, Operand(rcx, Context::SlotOffset(map_index))); 328 __ movq(rbx, Operand(rcx, Context::SlotOffset(map_index)));
329 __ movq(FieldOperand(rax, JSObject::kMapOffset), rbx); 329 __ movq(FieldOperand(rax, JSObject::kMapOffset), rbx);
330 330
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 rcx, 418 rcx,
419 Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST), 419 Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
420 rdx, 420 rdx,
421 rbx, 421 rbx,
422 kDontSaveFPRegs); 422 kDontSaveFPRegs);
423 423
424 // Return and remove the on-stack parameter. 424 // Return and remove the on-stack parameter.
425 __ ret(1 * kPointerSize); 425 __ ret(1 * kPointerSize);
426 426
427 __ bind(&restore); 427 __ bind(&restore);
428 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); 428 __ movq(rdx, StackOperandForArgument(1 * kPointerSize));
429 __ jmp(&install_unoptimized); 429 __ jmp(&install_unoptimized);
430 430
431 // Create a new closure through the slower runtime call. 431 // Create a new closure through the slower runtime call.
432 __ bind(&gc); 432 __ bind(&gc);
433 __ pop(rcx); // Temporarily remove return address. 433 __ pop(rcx); // Temporarily remove return address.
434 __ pop(rdx); 434 __ pop(rdx);
435 __ push(rsi); 435 __ push(rsi);
436 __ push(rdx); 436 __ push(rdx);
437 __ PushRoot(Heap::kFalseValueRootIndex); 437 __ PushRoot(Heap::kFalseValueRootIndex);
438 __ push(rcx); // Restore return address. 438 __ push(rcx); // Restore return address.
439 __ TailCallRuntime(Runtime::kNewClosure, 3, 1); 439 __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
440 } 440 }
441 441
442 442
443 void FastNewContextStub::Generate(MacroAssembler* masm) { 443 void FastNewContextStub::Generate(MacroAssembler* masm) {
444 // Try to allocate the context in new space. 444 // Try to allocate the context in new space.
445 Label gc; 445 Label gc;
446 int length = slots_ + Context::MIN_CONTEXT_SLOTS; 446 int length = slots_ + Context::MIN_CONTEXT_SLOTS;
447 __ Allocate((length * kPointerSize) + FixedArray::kHeaderSize, 447 __ Allocate((length * kPointerSize) + FixedArray::kHeaderSize,
448 rax, rbx, rcx, &gc, TAG_OBJECT); 448 rax, rbx, rcx, &gc, TAG_OBJECT);
449 449
450 // Get the function from the stack. 450 // Get the function from the stack.
451 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 451 __ movq(rcx, StackOperandForArgument(1 * kPointerSize));
452 452
453 // Set up the object header. 453 // Set up the object header.
454 __ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex); 454 __ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
455 __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister); 455 __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
456 __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length)); 456 __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
457 457
458 // Set up the fixed slots. 458 // Set up the fixed slots.
459 __ Set(rbx, 0); // Set to NULL. 459 __ Set(rbx, 0); // Set to NULL.
460 __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx); 460 __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
461 __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rsi); 461 __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rsi);
(...skipping 25 matching lines...) Expand all
487 // [rsp + (1 * kPointerSize)] : function 487 // [rsp + (1 * kPointerSize)] : function
488 // [rsp + (2 * kPointerSize)] : serialized scope info 488 // [rsp + (2 * kPointerSize)] : serialized scope info
489 489
490 // Try to allocate the context in new space. 490 // Try to allocate the context in new space.
491 Label gc; 491 Label gc;
492 int length = slots_ + Context::MIN_CONTEXT_SLOTS; 492 int length = slots_ + Context::MIN_CONTEXT_SLOTS;
493 __ Allocate(FixedArray::SizeFor(length), 493 __ Allocate(FixedArray::SizeFor(length),
494 rax, rbx, rcx, &gc, TAG_OBJECT); 494 rax, rbx, rcx, &gc, TAG_OBJECT);
495 495
496 // Get the function from the stack. 496 // Get the function from the stack.
497 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 497 __ movq(rcx, StackOperandForArgument(1 * kPointerSize));
498 498
499 // Get the serialized scope info from the stack. 499 // Get the serialized scope info from the stack.
500 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); 500 __ movq(rbx, StackOperandForArgument(2 * kPointerSize));
501 501
502 // Set up the object header. 502 // Set up the object header.
503 __ LoadRoot(kScratchRegister, Heap::kBlockContextMapRootIndex); 503 __ LoadRoot(kScratchRegister, Heap::kBlockContextMapRootIndex);
504 __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister); 504 __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
505 __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length)); 505 __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
506 506
507 // If this block context is nested in the native context we get a smi 507 // If this block context is nested in the native context we get a smi
508 // sentinel instead of a function. The block context should get the 508 // sentinel instead of a function. The block context should get the
509 // canonical empty function of the native context as its closure which 509 // canonical empty function of the native context as its closure which
510 // we still have to look up. 510 // we still have to look up.
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 // Output: 1269 // Output:
1270 // xmm1 : untagged double result. 1270 // xmm1 : untagged double result.
1271 1271
1272 Label runtime_call; 1272 Label runtime_call;
1273 Label runtime_call_clear_stack; 1273 Label runtime_call_clear_stack;
1274 Label skip_cache; 1274 Label skip_cache;
1275 const bool tagged = (argument_type_ == TAGGED); 1275 const bool tagged = (argument_type_ == TAGGED);
1276 if (tagged) { 1276 if (tagged) {
1277 Label input_not_smi, loaded; 1277 Label input_not_smi, loaded;
1278 // Test that rax is a number. 1278 // Test that rax is a number.
1279 __ movq(rax, Operand(rsp, kPointerSize)); 1279 __ movq(rax, StackOperandForArgument(1 * kPointerSize));
1280 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear); 1280 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
1281 // Input is a smi. Untag and load it onto the FPU stack. 1281 // Input is a smi. Untag and load it onto the FPU stack.
1282 // Then load the bits of the double into rbx. 1282 // Then load the bits of the double into rbx.
1283 __ SmiToInteger32(rax, rax); 1283 __ SmiToInteger32(rax, rax);
1284 __ subq(rsp, Immediate(kDoubleSize)); 1284 __ subq(rsp, Immediate(kDoubleSize));
1285 __ cvtlsi2sd(xmm1, rax); 1285 __ cvtlsi2sd(xmm1, rax);
1286 __ movsd(Operand(rsp, 0), xmm1); 1286 __ movsd(Operand(rsp, 0), xmm1);
1287 __ movq(rbx, xmm1); 1287 __ movq(rbx, xmm1);
1288 __ movq(rdx, xmm1); 1288 __ movq(rdx, xmm1);
1289 __ fld_d(Operand(rsp, 0)); 1289 __ fld_d(Operand(rsp, 0));
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1802 1802
1803 // Save 1 in double_result - we need this several times later on. 1803 // Save 1 in double_result - we need this several times later on.
1804 __ movq(scratch, Immediate(1)); 1804 __ movq(scratch, Immediate(1));
1805 __ cvtlsi2sd(double_result, scratch); 1805 __ cvtlsi2sd(double_result, scratch);
1806 1806
1807 if (exponent_type_ == ON_STACK) { 1807 if (exponent_type_ == ON_STACK) {
1808 Label base_is_smi, unpack_exponent; 1808 Label base_is_smi, unpack_exponent;
1809 // The exponent and base are supplied as arguments on the stack. 1809 // The exponent and base are supplied as arguments on the stack.
1810 // This can only happen if the stub is called from non-optimized code. 1810 // This can only happen if the stub is called from non-optimized code.
1811 // Load input parameters from stack. 1811 // Load input parameters from stack.
1812 __ movq(base, Operand(rsp, 2 * kPointerSize)); 1812 __ movq(base, StackOperandForArgument(2 * kPointerSize));
1813 __ movq(exponent, Operand(rsp, 1 * kPointerSize)); 1813 __ movq(exponent, StackOperandForArgument(1 * kPointerSize));
1814 __ JumpIfSmi(base, &base_is_smi, Label::kNear); 1814 __ JumpIfSmi(base, &base_is_smi, Label::kNear);
1815 __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset), 1815 __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
1816 Heap::kHeapNumberMapRootIndex); 1816 Heap::kHeapNumberMapRootIndex);
1817 __ j(not_equal, &call_runtime); 1817 __ j(not_equal, &call_runtime);
1818 1818
1819 __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset)); 1819 __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
1820 __ jmp(&unpack_exponent, Label::kNear); 1820 __ jmp(&unpack_exponent, Label::kNear);
1821 1821
1822 __ bind(&base_is_smi); 1822 __ bind(&base_is_smi);
1823 __ SmiToInteger32(base, base); 1823 __ SmiToInteger32(base, base);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 // rsp[0] : return address 2236 // rsp[0] : return address
2237 // rsp[8] : number of parameters (tagged) 2237 // rsp[8] : number of parameters (tagged)
2238 // rsp[16] : receiver displacement 2238 // rsp[16] : receiver displacement
2239 // rsp[24] : function 2239 // rsp[24] : function
2240 // Registers used over the whole function: 2240 // Registers used over the whole function:
2241 // rbx: the mapped parameter count (untagged) 2241 // rbx: the mapped parameter count (untagged)
2242 // rax: the allocated object (tagged). 2242 // rax: the allocated object (tagged).
2243 2243
2244 Factory* factory = masm->isolate()->factory(); 2244 Factory* factory = masm->isolate()->factory();
2245 2245
2246 __ SmiToInteger64(rbx, Operand(rsp, 1 * kPointerSize)); 2246 __ SmiToInteger64(rbx, StackOperandForArgument(1 * kPointerSize));
2247 // rbx = parameter count (untagged) 2247 // rbx = parameter count (untagged)
2248 2248
2249 // Check if the calling frame is an arguments adaptor frame. 2249 // Check if the calling frame is an arguments adaptor frame.
2250 Label runtime; 2250 Label runtime;
2251 Label adaptor_frame, try_allocate; 2251 Label adaptor_frame, try_allocate;
2252 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2252 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2253 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 2253 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
2254 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2254 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2255 __ j(equal, &adaptor_frame); 2255 __ j(equal, &adaptor_frame);
2256 2256
2257 // No adaptor, parameter count = argument count. 2257 // No adaptor, parameter count = argument count.
2258 __ movq(rcx, rbx); 2258 __ movq(rcx, rbx);
2259 __ jmp(&try_allocate, Label::kNear); 2259 __ jmp(&try_allocate, Label::kNear);
2260 2260
2261 // We have an adaptor frame. Patch the parameters pointer. 2261 // We have an adaptor frame. Patch the parameters pointer.
2262 __ bind(&adaptor_frame); 2262 __ bind(&adaptor_frame);
2263 __ SmiToInteger64(rcx, 2263 __ SmiToInteger64(rcx,
2264 Operand(rdx, 2264 Operand(rdx,
2265 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2265 ArgumentsAdaptorFrameConstants::kLengthOffset));
2266 __ lea(rdx, Operand(rdx, rcx, times_pointer_size, 2266 __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
2267 StandardFrameConstants::kCallerSPOffset)); 2267 StandardFrameConstants::kCallerSPOffset));
2268 __ movq(Operand(rsp, 2 * kPointerSize), rdx); 2268 __ movq(StackOperandForArgument(2 * kPointerSize), rdx);
2269 2269
2270 // rbx = parameter count (untagged) 2270 // rbx = parameter count (untagged)
2271 // rcx = argument count (untagged) 2271 // rcx = argument count (untagged)
2272 // Compute the mapped parameter count = min(rbx, rcx) in rbx. 2272 // Compute the mapped parameter count = min(rbx, rcx) in rbx.
2273 __ cmpq(rbx, rcx); 2273 __ cmpq(rbx, rcx);
2274 __ j(less_equal, &try_allocate, Label::kNear); 2274 __ j(less_equal, &try_allocate, Label::kNear);
2275 __ movq(rbx, rcx); 2275 __ movq(rbx, rcx);
2276 2276
2277 __ bind(&try_allocate); 2277 __ bind(&try_allocate);
2278 2278
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 // rcx = argument count (untagged) 2319 // rcx = argument count (untagged)
2320 // rdi = address of boilerplate object (tagged) 2320 // rdi = address of boilerplate object (tagged)
2321 // Copy the JS object part. 2321 // Copy the JS object part.
2322 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { 2322 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
2323 __ movq(rdx, FieldOperand(rdi, i)); 2323 __ movq(rdx, FieldOperand(rdi, i));
2324 __ movq(FieldOperand(rax, i), rdx); 2324 __ movq(FieldOperand(rax, i), rdx);
2325 } 2325 }
2326 2326
2327 // Set up the callee in-object property. 2327 // Set up the callee in-object property.
2328 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 2328 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
2329 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); 2329 __ movq(rdx, StackOperandForArgument(3 * kPointerSize));
2330 __ movq(FieldOperand(rax, JSObject::kHeaderSize + 2330 __ movq(FieldOperand(rax, JSObject::kHeaderSize +
2331 Heap::kArgumentsCalleeIndex * kPointerSize), 2331 Heap::kArgumentsCalleeIndex * kPointerSize),
2332 rdx); 2332 rdx);
2333 2333
2334 // Use the length (smi tagged) and set that as an in-object property too. 2334 // Use the length (smi tagged) and set that as an in-object property too.
2335 // Note: rcx is tagged from here on. 2335 // Note: rcx is tagged from here on.
2336 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 2336 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
2337 __ Integer32ToSmi(rcx, rcx); 2337 __ Integer32ToSmi(rcx, rcx);
2338 __ movq(FieldOperand(rax, JSObject::kHeaderSize + 2338 __ movq(FieldOperand(rax, JSObject::kHeaderSize +
2339 Heap::kArgumentsLengthIndex * kPointerSize), 2339 Heap::kArgumentsLengthIndex * kPointerSize),
(...skipping 30 matching lines...) Expand all
2370 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 2370 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
2371 // The mapped parameter thus need to get indices 2371 // The mapped parameter thus need to get indices
2372 // MIN_CONTEXT_SLOTS+parameter_count-1 .. 2372 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
2373 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count 2373 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
2374 // We loop from right to left. 2374 // We loop from right to left.
2375 Label parameters_loop, parameters_test; 2375 Label parameters_loop, parameters_test;
2376 2376
2377 // Load tagged parameter count into r9. 2377 // Load tagged parameter count into r9.
2378 __ Integer32ToSmi(r9, rbx); 2378 __ Integer32ToSmi(r9, rbx);
2379 __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS)); 2379 __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
2380 __ addq(r8, Operand(rsp, 1 * kPointerSize)); 2380 __ addq(r8, StackOperandForArgument(1 * kPointerSize));
2381 __ subq(r8, r9); 2381 __ subq(r8, r9);
2382 __ Move(r11, factory->the_hole_value()); 2382 __ Move(r11, factory->the_hole_value());
2383 __ movq(rdx, rdi); 2383 __ movq(rdx, rdi);
2384 __ lea(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); 2384 __ lea(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
2385 // r9 = loop variable (tagged) 2385 // r9 = loop variable (tagged)
2386 // r8 = mapping index (tagged) 2386 // r8 = mapping index (tagged)
2387 // r11 = the hole value 2387 // r11 = the hole value
2388 // rdx = address of parameter map (tagged) 2388 // rdx = address of parameter map (tagged)
2389 // rdi = address of backing store (tagged) 2389 // rdi = address of backing store (tagged)
2390 __ jmp(&parameters_test, Label::kNear); 2390 __ jmp(&parameters_test, Label::kNear);
(...skipping 18 matching lines...) Expand all
2409 2409
2410 // rcx = argument count (tagged) 2410 // rcx = argument count (tagged)
2411 // rdi = address of backing store (tagged) 2411 // rdi = address of backing store (tagged)
2412 // Copy arguments header and remaining slots (if there are any). 2412 // Copy arguments header and remaining slots (if there are any).
2413 __ Move(FieldOperand(rdi, FixedArray::kMapOffset), 2413 __ Move(FieldOperand(rdi, FixedArray::kMapOffset),
2414 factory->fixed_array_map()); 2414 factory->fixed_array_map());
2415 __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); 2415 __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
2416 2416
2417 Label arguments_loop, arguments_test; 2417 Label arguments_loop, arguments_test;
2418 __ movq(r8, rbx); 2418 __ movq(r8, rbx);
2419 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2419 __ movq(rdx, StackOperandForArgument(2 * kPointerSize));
2420 // Untag rcx for the loop below. 2420 // Untag rcx for the loop below.
2421 __ SmiToInteger64(rcx, rcx); 2421 __ SmiToInteger64(rcx, rcx);
2422 __ lea(kScratchRegister, Operand(r8, times_pointer_size, 0)); 2422 __ lea(kScratchRegister, Operand(r8, times_pointer_size, 0));
2423 __ subq(rdx, kScratchRegister); 2423 __ subq(rdx, kScratchRegister);
2424 __ jmp(&arguments_test, Label::kNear); 2424 __ jmp(&arguments_test, Label::kNear);
2425 2425
2426 __ bind(&arguments_loop); 2426 __ bind(&arguments_loop);
2427 __ subq(rdx, Immediate(kPointerSize)); 2427 __ subq(rdx, Immediate(kPointerSize));
2428 __ movq(r9, Operand(rdx, 0)); 2428 __ movq(r9, Operand(rdx, 0));
2429 __ movq(FieldOperand(rdi, r8, 2429 __ movq(FieldOperand(rdi, r8,
2430 times_pointer_size, 2430 times_pointer_size,
2431 FixedArray::kHeaderSize), 2431 FixedArray::kHeaderSize),
2432 r9); 2432 r9);
2433 __ addq(r8, Immediate(1)); 2433 __ addq(r8, Immediate(1));
2434 2434
2435 __ bind(&arguments_test); 2435 __ bind(&arguments_test);
2436 __ cmpq(r8, rcx); 2436 __ cmpq(r8, rcx);
2437 __ j(less, &arguments_loop, Label::kNear); 2437 __ j(less, &arguments_loop, Label::kNear);
2438 2438
2439 // Return and remove the on-stack parameters. 2439 // Return and remove the on-stack parameters.
2440 __ ret(3 * kPointerSize); 2440 __ ret(3 * kPointerSize);
2441 2441
2442 // Do the runtime call to allocate the arguments object. 2442 // Do the runtime call to allocate the arguments object.
2443 // rcx = argument count (untagged) 2443 // rcx = argument count (untagged)
2444 __ bind(&runtime); 2444 __ bind(&runtime);
2445 __ Integer32ToSmi(rcx, rcx); 2445 __ Integer32ToSmi(rcx, rcx);
2446 __ movq(Operand(rsp, 1 * kPointerSize), rcx); // Patch argument count. 2446 // Patch argument count.
2447 __ movq(StackOperandForArgument(1 * kPointerSize), rcx);
2447 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 2448 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
2448 } 2449 }
2449 2450
2450 2451
2451 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { 2452 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
2452 // rsp[0] : return address 2453 // rsp[0] : return address
2453 // rsp[8] : number of parameters 2454 // rsp[8] : number of parameters
2454 // rsp[16] : receiver displacement 2455 // rsp[16] : receiver displacement
2455 // rsp[24] : function 2456 // rsp[24] : function
2456 2457
2457 // Check if the calling frame is an arguments adaptor frame. 2458 // Check if the calling frame is an arguments adaptor frame.
2458 Label runtime; 2459 Label runtime;
2459 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2460 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2460 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 2461 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
2461 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2462 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2462 __ j(not_equal, &runtime); 2463 __ j(not_equal, &runtime);
2463 2464
2464 // Patch the arguments.length and the parameters pointer. 2465 // Patch the arguments.length and the parameters pointer.
2465 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2466 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
2466 __ movq(Operand(rsp, 1 * kPointerSize), rcx); 2467 __ movq(StackOperandForArgument(1 * kPointerSize), rcx);
2467 __ SmiToInteger64(rcx, rcx); 2468 __ SmiToInteger64(rcx, rcx);
2468 __ lea(rdx, Operand(rdx, rcx, times_pointer_size, 2469 __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
2469 StandardFrameConstants::kCallerSPOffset)); 2470 StandardFrameConstants::kCallerSPOffset));
2470 __ movq(Operand(rsp, 2 * kPointerSize), rdx); 2471 __ movq(StackOperandForArgument(2 * kPointerSize), rdx);
2471 2472
2472 __ bind(&runtime); 2473 __ bind(&runtime);
2473 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 2474 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
2474 } 2475 }
2475 2476
2476 2477
2477 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 2478 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
2478 // rsp[0] : return address 2479 // rsp[0] : return address
2479 // rsp[8] : number of parameters 2480 // rsp[8] : number of parameters
2480 // rsp[16] : receiver displacement 2481 // rsp[16] : receiver displacement
2481 // rsp[24] : function 2482 // rsp[24] : function
2482 2483
2483 // Check if the calling frame is an arguments adaptor frame. 2484 // Check if the calling frame is an arguments adaptor frame.
2484 Label adaptor_frame, try_allocate, runtime; 2485 Label adaptor_frame, try_allocate, runtime;
2485 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2486 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2486 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 2487 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
2487 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2488 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2488 __ j(equal, &adaptor_frame); 2489 __ j(equal, &adaptor_frame);
2489 2490
2490 // Get the length from the frame. 2491 // Get the length from the frame.
2491 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 2492 __ movq(rcx, StackOperandForArgument(1 * kPointerSize));
2492 __ SmiToInteger64(rcx, rcx); 2493 __ SmiToInteger64(rcx, rcx);
2493 __ jmp(&try_allocate); 2494 __ jmp(&try_allocate);
2494 2495
2495 // Patch the arguments.length and the parameters pointer. 2496 // Patch the arguments.length and the parameters pointer.
2496 __ bind(&adaptor_frame); 2497 __ bind(&adaptor_frame);
2497 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2498 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
2498 __ movq(Operand(rsp, 1 * kPointerSize), rcx); 2499 __ movq(StackOperandForArgument(1 * kPointerSize), rcx);
2499 __ SmiToInteger64(rcx, rcx); 2500 __ SmiToInteger64(rcx, rcx);
2500 __ lea(rdx, Operand(rdx, rcx, times_pointer_size, 2501 __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
2501 StandardFrameConstants::kCallerSPOffset)); 2502 StandardFrameConstants::kCallerSPOffset));
2502 __ movq(Operand(rsp, 2 * kPointerSize), rdx); 2503 __ movq(StackOperandForArgument(2 * kPointerSize), rdx);
2503 2504
2504 // Try the new space allocation. Start out with computing the size of 2505 // Try the new space allocation. Start out with computing the size of
2505 // the arguments object and the elements array. 2506 // the arguments object and the elements array.
2506 Label add_arguments_object; 2507 Label add_arguments_object;
2507 __ bind(&try_allocate); 2508 __ bind(&try_allocate);
2508 __ testq(rcx, rcx); 2509 __ testq(rcx, rcx);
2509 __ j(zero, &add_arguments_object, Label::kNear); 2510 __ j(zero, &add_arguments_object, Label::kNear);
2510 __ lea(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize)); 2511 __ lea(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
2511 __ bind(&add_arguments_object); 2512 __ bind(&add_arguments_object);
2512 __ addq(rcx, Immediate(Heap::kArgumentsObjectSizeStrict)); 2513 __ addq(rcx, Immediate(Heap::kArgumentsObjectSizeStrict));
2513 2514
2514 // Do the allocation of both objects in one go. 2515 // Do the allocation of both objects in one go.
2515 __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT); 2516 __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
2516 2517
2517 // Get the arguments boilerplate from the current native context. 2518 // Get the arguments boilerplate from the current native context.
2518 __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 2519 __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
2519 __ movq(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); 2520 __ movq(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
2520 const int offset = 2521 const int offset =
2521 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); 2522 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
2522 __ movq(rdi, Operand(rdi, offset)); 2523 __ movq(rdi, Operand(rdi, offset));
2523 2524
2524 // Copy the JS object part. 2525 // Copy the JS object part.
2525 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { 2526 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
2526 __ movq(rbx, FieldOperand(rdi, i)); 2527 __ movq(rbx, FieldOperand(rdi, i));
2527 __ movq(FieldOperand(rax, i), rbx); 2528 __ movq(FieldOperand(rax, i), rbx);
2528 } 2529 }
2529 2530
2530 // Get the length (smi tagged) and set that as an in-object property too. 2531 // Get the length (smi tagged) and set that as an in-object property too.
2531 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 2532 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
2532 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 2533 __ movq(rcx, StackOperandForArgument(1 * kPointerSize));
2533 __ movq(FieldOperand(rax, JSObject::kHeaderSize + 2534 __ movq(FieldOperand(rax, JSObject::kHeaderSize +
2534 Heap::kArgumentsLengthIndex * kPointerSize), 2535 Heap::kArgumentsLengthIndex * kPointerSize),
2535 rcx); 2536 rcx);
2536 2537
2537 // If there are no actual arguments, we're done. 2538 // If there are no actual arguments, we're done.
2538 Label done; 2539 Label done;
2539 __ testq(rcx, rcx); 2540 __ testq(rcx, rcx);
2540 __ j(zero, &done); 2541 __ j(zero, &done);
2541 2542
2542 // Get the parameters pointer from the stack. 2543 // Get the parameters pointer from the stack.
2543 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2544 __ movq(rdx, StackOperandForArgument(2 * kPointerSize));
2544 2545
2545 // Set up the elements pointer in the allocated arguments object and 2546 // Set up the elements pointer in the allocated arguments object and
2546 // initialize the header in the elements fixed array. 2547 // initialize the header in the elements fixed array.
2547 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSizeStrict)); 2548 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSizeStrict));
2548 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi); 2549 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
2549 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); 2550 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
2550 __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); 2551 __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
2551 2552
2552 2553
2553 __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); 2554 __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
3016 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); 3017 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
3017 __ jmp(&check_underlying); 3018 __ jmp(&check_underlying);
3018 #endif // V8_INTERPRETED_REGEXP 3019 #endif // V8_INTERPRETED_REGEXP
3019 } 3020 }
3020 3021
3021 3022
3022 void RegExpConstructResultStub::Generate(MacroAssembler* masm) { 3023 void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
3023 const int kMaxInlineLength = 100; 3024 const int kMaxInlineLength = 100;
3024 Label slowcase; 3025 Label slowcase;
3025 Label done; 3026 Label done;
3026 __ movq(r8, Operand(rsp, kPointerSize * 3)); 3027 __ movq(r8, StackOperandForArgument(3 * kPointerSize));
3027 __ JumpIfNotSmi(r8, &slowcase); 3028 __ JumpIfNotSmi(r8, &slowcase);
3028 __ SmiToInteger32(rbx, r8); 3029 __ SmiToInteger32(rbx, r8);
3029 __ cmpl(rbx, Immediate(kMaxInlineLength)); 3030 __ cmpl(rbx, Immediate(kMaxInlineLength));
3030 __ j(above, &slowcase); 3031 __ j(above, &slowcase);
3031 // Smi-tagging is equivalent to multiplying by 2. 3032 // Smi-tagging is equivalent to multiplying by 2.
3032 STATIC_ASSERT(kSmiTag == 0); 3033 STATIC_ASSERT(kSmiTag == 0);
3033 STATIC_ASSERT(kSmiTagSize == 1); 3034 STATIC_ASSERT(kSmiTagSize == 1);
3034 // Allocate RegExpResult followed by FixedArray with size in rbx. 3035 // Allocate RegExpResult followed by FixedArray with size in rbx.
3035 // JSArray: [Map][empty properties][Elements][Length-smi][index][input] 3036 // JSArray: [Map][empty properties][Elements][Length-smi][index][input]
3036 // Elements: [Map][Length][..elements..] 3037 // Elements: [Map][Length][..elements..]
(...skipping 17 matching lines...) Expand all
3054 3055
3055 // Set empty properties FixedArray. 3056 // Set empty properties FixedArray.
3056 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); 3057 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
3057 __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); 3058 __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
3058 3059
3059 // Set elements to point to FixedArray allocated right after the JSArray. 3060 // Set elements to point to FixedArray allocated right after the JSArray.
3060 __ lea(rcx, Operand(rax, JSRegExpResult::kSize)); 3061 __ lea(rcx, Operand(rax, JSRegExpResult::kSize));
3061 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx); 3062 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
3062 3063
3063 // Set input, index and length fields from arguments. 3064 // Set input, index and length fields from arguments.
3064 __ movq(r8, Operand(rsp, kPointerSize * 1)); 3065 __ movq(r8, StackOperandForArgument(1 * kPointerSize));
3065 __ movq(FieldOperand(rax, JSRegExpResult::kInputOffset), r8); 3066 __ movq(FieldOperand(rax, JSRegExpResult::kInputOffset), r8);
3066 __ movq(r8, Operand(rsp, kPointerSize * 2)); 3067 __ movq(r8, StackOperandForArgument(2 * kPointerSize));
3067 __ movq(FieldOperand(rax, JSRegExpResult::kIndexOffset), r8); 3068 __ movq(FieldOperand(rax, JSRegExpResult::kIndexOffset), r8);
3068 __ movq(r8, Operand(rsp, kPointerSize * 3)); 3069 __ movq(r8, StackOperandForArgument(3 * kPointerSize));
3069 __ movq(FieldOperand(rax, JSArray::kLengthOffset), r8); 3070 __ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);
3070 3071
3071 // Fill out the elements FixedArray. 3072 // Fill out the elements FixedArray.
3072 // rax: JSArray. 3073 // rax: JSArray.
3073 // rcx: FixedArray. 3074 // rcx: FixedArray.
3074 // rbx: Number of elements in array as int32. 3075 // rbx: Number of elements in array as int32.
3075 3076
3076 // Set map. 3077 // Set map.
3077 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); 3078 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
3078 __ movq(FieldOperand(rcx, HeapObject::kMapOffset), kScratchRegister); 3079 __ movq(FieldOperand(rcx, HeapObject::kMapOffset), kScratchRegister);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 // but times_twice_pointer_size (multiplication by 16) scale factor 3190 // but times_twice_pointer_size (multiplication by 16) scale factor
3190 // is not supported by addrmode on x64 platform. 3191 // is not supported by addrmode on x64 platform.
3191 // So we have to premultiply entry index before lookup. 3192 // So we have to premultiply entry index before lookup.
3192 __ shl(hash, Immediate(kPointerSizeLog2 + 1)); 3193 __ shl(hash, Immediate(kPointerSizeLog2 + 1));
3193 } 3194 }
3194 3195
3195 3196
3196 void NumberToStringStub::Generate(MacroAssembler* masm) { 3197 void NumberToStringStub::Generate(MacroAssembler* masm) {
3197 Label runtime; 3198 Label runtime;
3198 3199
3199 __ movq(rbx, Operand(rsp, kPointerSize)); 3200 __ movq(rbx, StackOperandForArgument(1 * kPointerSize));
3200 3201
3201 // Generate code to lookup number in the number string cache. 3202 // Generate code to lookup number in the number string cache.
3202 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime); 3203 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime);
3203 __ ret(1 * kPointerSize); 3204 __ ret(1 * kPointerSize);
3204 3205
3205 __ bind(&runtime); 3206 __ bind(&runtime);
3206 // Handle number to string in the runtime system if not found in the cache. 3207 // Handle number to string in the runtime system if not found in the cache.
3207 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); 3208 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1);
3208 } 3209 }
3209 3210
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
3609 Isolate* isolate = masm->isolate(); 3610 Isolate* isolate = masm->isolate();
3610 Label slow, non_function; 3611 Label slow, non_function;
3611 3612
3612 // The receiver might implicitly be the global object. This is 3613 // The receiver might implicitly be the global object. This is
3613 // indicated by passing the hole as the receiver to the call 3614 // indicated by passing the hole as the receiver to the call
3614 // function stub. 3615 // function stub.
3615 if (ReceiverMightBeImplicit()) { 3616 if (ReceiverMightBeImplicit()) {
3616 Label call; 3617 Label call;
3617 // Get the receiver from the stack. 3618 // Get the receiver from the stack.
3618 // +1 ~ return address 3619 // +1 ~ return address
3619 __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize)); 3620 __ movq(rax, StackOperandForArgument((argc_ + 1) * kPointerSize));
3620 // Call as function is indicated with the hole. 3621 // Call as function is indicated with the hole.
3621 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 3622 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
3622 __ j(not_equal, &call, Label::kNear); 3623 __ j(not_equal, &call, Label::kNear);
3623 // Patch the receiver on the stack with the global receiver object. 3624 // Patch the receiver on the stack with the global receiver object.
3624 __ movq(rcx, GlobalObjectOperand()); 3625 __ movq(rcx, GlobalObjectOperand());
3625 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 3626 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
3626 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx); 3627 __ movq(StackOperandForArgument((argc_ + 1) * kPointerSize), rcx);
3627 __ bind(&call); 3628 __ bind(&call);
3628 } 3629 }
3629 3630
3630 // Check that the function really is a JavaScript function. 3631 // Check that the function really is a JavaScript function.
3631 __ JumpIfSmi(rdi, &non_function); 3632 __ JumpIfSmi(rdi, &non_function);
3632 // Goto slow case if we do not have a function. 3633 // Goto slow case if we do not have a function.
3633 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 3634 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
3634 __ j(not_equal, &slow); 3635 __ j(not_equal, &slow);
3635 3636
3636 if (RecordCallTarget()) { 3637 if (RecordCallTarget()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3678 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); 3679 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
3679 { 3680 {
3680 Handle<Code> adaptor = 3681 Handle<Code> adaptor =
3681 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 3682 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
3682 __ jmp(adaptor, RelocInfo::CODE_TARGET); 3683 __ jmp(adaptor, RelocInfo::CODE_TARGET);
3683 } 3684 }
3684 3685
3685 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 3686 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3686 // of the original receiver from the call site). 3687 // of the original receiver from the call site).
3687 __ bind(&non_function); 3688 __ bind(&non_function);
3688 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi); 3689 __ movq(StackOperandForArgument((argc_ + 1) * kPointerSize), rdi);
3689 __ Set(rax, argc_); 3690 __ Set(rax, argc_);
3690 __ Set(rbx, 0); 3691 __ Set(rbx, 0);
3691 __ SetCallKind(rcx, CALL_AS_METHOD); 3692 __ SetCallKind(rcx, CALL_AS_METHOD);
3692 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); 3693 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
3693 Handle<Code> adaptor = 3694 Handle<Code> adaptor =
3694 Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline(); 3695 Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline();
3695 __ Jump(adaptor, RelocInfo::CODE_TARGET); 3696 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3696 } 3697 }
3697 3698
3698 3699
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space)); 4229 __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space));
4229 __ JumpIfSmi(rax, &slow); 4230 __ JumpIfSmi(rax, &slow);
4230 4231
4231 // Check that the left hand is a JS object. Leave its map in rax. 4232 // Check that the left hand is a JS object. Leave its map in rax.
4232 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax); 4233 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax);
4233 __ j(below, &slow); 4234 __ j(below, &slow);
4234 __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE); 4235 __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE);
4235 __ j(above, &slow); 4236 __ j(above, &slow);
4236 4237
4237 // Get the prototype of the function. 4238 // Get the prototype of the function.
4238 __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space)); 4239 __ movq(rdx, StackOperandForArgument(1 * kPointerSize + extra_stack_space));
4239 // rdx is function, rax is map. 4240 // rdx is function, rax is map.
4240 4241
4241 // If there is a call site cache don't look in the global cache, but do the 4242 // If there is a call site cache don't look in the global cache, but do the
4242 // real lookup and update the call site cache. 4243 // real lookup and update the call site cache.
4243 if (!HasCallSiteInlineCheck()) { 4244 if (!HasCallSiteInlineCheck()) {
4244 // Look up the function and the map in the instanceof cache. 4245 // Look up the function and the map in the instanceof cache.
4245 Label miss; 4246 Label miss;
4246 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); 4247 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
4247 __ j(not_equal, &miss, Label::kNear); 4248 __ j(not_equal, &miss, Label::kNear);
4248 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex); 4249 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex);
(...skipping 15 matching lines...) Expand all
4264 // Register mapping: 4265 // Register mapping:
4265 // rax is object map. 4266 // rax is object map.
4266 // rdx is function. 4267 // rdx is function.
4267 // rbx is function prototype. 4268 // rbx is function prototype.
4268 if (!HasCallSiteInlineCheck()) { 4269 if (!HasCallSiteInlineCheck()) {
4269 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); 4270 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
4270 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex); 4271 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex);
4271 } else { 4272 } else {
4272 // Get return address and delta to inlined map check. 4273 // Get return address and delta to inlined map check.
4273 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); 4274 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
4274 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); 4275 __ subq(kScratchRegister, StackOperandForArgument(1 * kPointerSize));
4275 if (FLAG_debug_code) { 4276 if (FLAG_debug_code) {
4276 __ movl(rdi, Immediate(kWordBeforeMapCheckValue)); 4277 __ movl(rdi, Immediate(kWordBeforeMapCheckValue));
4277 __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi); 4278 __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi);
4278 __ Assert(equal, "InstanceofStub unexpected call site cache (check)."); 4279 __ Assert(equal, "InstanceofStub unexpected call site cache (check).");
4279 } 4280 }
4280 __ movq(kScratchRegister, 4281 __ movq(kScratchRegister,
4281 Operand(kScratchRegister, kOffsetToMapCheckValue)); 4282 Operand(kScratchRegister, kOffsetToMapCheckValue));
4282 __ movq(Operand(kScratchRegister, 0), rax); 4283 __ movq(Operand(kScratchRegister, 0), rax);
4283 } 4284 }
4284 4285
(...skipping 20 matching lines...) Expand all
4305 STATIC_ASSERT(kSmiTag == 0); 4306 STATIC_ASSERT(kSmiTag == 0);
4306 __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); 4307 __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
4307 } else { 4308 } else {
4308 // Store offset of true in the root array at the inline check site. 4309 // Store offset of true in the root array at the inline check site.
4309 int true_offset = 0x100 + 4310 int true_offset = 0x100 +
4310 (Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias; 4311 (Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias;
4311 // Assert it is a 1-byte signed value. 4312 // Assert it is a 1-byte signed value.
4312 ASSERT(true_offset >= 0 && true_offset < 0x100); 4313 ASSERT(true_offset >= 0 && true_offset < 0x100);
4313 __ movl(rax, Immediate(true_offset)); 4314 __ movl(rax, Immediate(true_offset));
4314 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); 4315 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
4315 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); 4316 __ subq(kScratchRegister, StackOperandForArgument(1 * kPointerSize));
4316 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); 4317 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
4317 if (FLAG_debug_code) { 4318 if (FLAG_debug_code) {
4318 __ movl(rax, Immediate(kWordBeforeResultValue)); 4319 __ movl(rax, Immediate(kWordBeforeResultValue));
4319 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); 4320 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
4320 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)."); 4321 __ Assert(equal, "InstanceofStub unexpected call site cache (mov).");
4321 } 4322 }
4322 __ Set(rax, 0); 4323 __ Set(rax, 0);
4323 } 4324 }
4324 __ ret(2 * kPointerSize + extra_stack_space); 4325 __ ret(2 * kPointerSize + extra_stack_space);
4325 4326
4326 __ bind(&is_not_instance); 4327 __ bind(&is_not_instance);
4327 if (!HasCallSiteInlineCheck()) { 4328 if (!HasCallSiteInlineCheck()) {
4328 // We have to store a non-zero value in the cache. 4329 // We have to store a non-zero value in the cache.
4329 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); 4330 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex);
4330 } else { 4331 } else {
4331 // Store offset of false in the root array at the inline check site. 4332 // Store offset of false in the root array at the inline check site.
4332 int false_offset = 0x100 + 4333 int false_offset = 0x100 +
4333 (Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias; 4334 (Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias;
4334 // Assert it is a 1-byte signed value. 4335 // Assert it is a 1-byte signed value.
4335 ASSERT(false_offset >= 0 && false_offset < 0x100); 4336 ASSERT(false_offset >= 0 && false_offset < 0x100);
4336 __ movl(rax, Immediate(false_offset)); 4337 __ movl(rax, Immediate(false_offset));
4337 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); 4338 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
4338 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); 4339 __ subq(kScratchRegister, StackOperandForArgument(1 * kPointerSize));
4339 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); 4340 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
4340 if (FLAG_debug_code) { 4341 if (FLAG_debug_code) {
4341 __ movl(rax, Immediate(kWordBeforeResultValue)); 4342 __ movl(rax, Immediate(kWordBeforeResultValue));
4342 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); 4343 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
4343 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)"); 4344 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)");
4344 } 4345 }
4345 } 4346 }
4346 __ ret(2 * kPointerSize + extra_stack_space); 4347 __ ret(2 * kPointerSize + extra_stack_space);
4347 4348
4348 // Slow-case: Go through the JavaScript implementation. 4349 // Slow-case: Go through the JavaScript implementation.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
4494 4495
4495 __ Abort("Unexpected fallthrough from CharFromCode slow case"); 4496 __ Abort("Unexpected fallthrough from CharFromCode slow case");
4496 } 4497 }
4497 4498
4498 4499
4499 void StringAddStub::Generate(MacroAssembler* masm) { 4500 void StringAddStub::Generate(MacroAssembler* masm) {
4500 Label call_runtime, call_builtin; 4501 Label call_runtime, call_builtin;
4501 Builtins::JavaScript builtin_id = Builtins::ADD; 4502 Builtins::JavaScript builtin_id = Builtins::ADD;
4502 4503
4503 // Load the two arguments. 4504 // Load the two arguments.
4504 __ movq(rax, Operand(rsp, 2 * kPointerSize)); // First argument (left). 4505 __ movq(rax, StackOperandForArgument(2 * kPointerSize)); // First (left).
4505 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); // Second argument (right). 4506 __ movq(rdx, StackOperandForArgument(1 * kPointerSize)); // Second (right).
4506 4507
4507 // Make sure that both arguments are strings if not known in advance. 4508 // Make sure that both arguments are strings if not known in advance.
4508 // Otherwise, at least one of the arguments is definitely a string, 4509 // Otherwise, at least one of the arguments is definitely a string,
4509 // and we convert the one that is not known to be a string. 4510 // and we convert the one that is not known to be a string.
4510 if ((flags_ & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { 4511 if ((flags_ & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
4511 ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT); 4512 ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT);
4512 ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT); 4513 ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT);
4513 __ JumpIfSmi(rax, &call_runtime); 4514 __ JumpIfSmi(rax, &call_runtime);
4514 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, r8); 4515 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, r8);
4515 __ j(above_equal, &call_runtime); 4516 __ j(above_equal, &call_runtime);
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after
5502 5503
5503 5504
5504 void StringCompareStub::Generate(MacroAssembler* masm) { 5505 void StringCompareStub::Generate(MacroAssembler* masm) {
5505 Label runtime; 5506 Label runtime;
5506 5507
5507 // Stack frame on entry. 5508 // Stack frame on entry.
5508 // rsp[0] : return address 5509 // rsp[0] : return address
5509 // rsp[8] : right string 5510 // rsp[8] : right string
5510 // rsp[16] : left string 5511 // rsp[16] : left string
5511 5512
5512 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left 5513 __ movq(rdx, StackOperandForArgument(2 * kPointerSize)); // left
5513 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right 5514 __ movq(rax, StackOperandForArgument(1 * kPointerSize)); // right
5514 5515
5515 // Check for identity. 5516 // Check for identity.
5516 Label not_same; 5517 Label not_same;
5517 __ cmpq(rdx, rax); 5518 __ cmpq(rdx, rax);
5518 __ j(not_equal, &not_same, Label::kNear); 5519 __ j(not_equal, &not_same, Label::kNear);
5519 __ Move(rax, Smi::FromInt(EQUAL)); 5520 __ Move(rax, Smi::FromInt(EQUAL));
5520 Counters* counters = masm->isolate()->counters(); 5521 Counters* counters = masm->isolate()->counters();
5521 __ IncrementCounter(counters->string_compare_native(), 1); 5522 __ IncrementCounter(counters->string_compare_native(), 1);
5522 __ ret(2 * kPointerSize); 5523 __ ret(2 * kPointerSize);
5523 5524
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
6018 __ decl(scratch); 6019 __ decl(scratch);
6019 __ push(scratch); 6020 __ push(scratch);
6020 6021
6021 // If names of slots in range from 1 to kProbes - 1 for the hash value are 6022 // If names of slots in range from 1 to kProbes - 1 for the hash value are
6022 // not equal to the name and kProbes-th slot is not used (its name is the 6023 // not equal to the name and kProbes-th slot is not used (its name is the
6023 // undefined value), it guarantees the hash table doesn't contain the 6024 // undefined value), it guarantees the hash table doesn't contain the
6024 // property. It's true even if some slots represent deleted properties 6025 // property. It's true even if some slots represent deleted properties
6025 // (their names are the null value). 6026 // (their names are the null value).
6026 for (int i = kInlinedProbes; i < kTotalProbes; i++) { 6027 for (int i = kInlinedProbes; i < kTotalProbes; i++) {
6027 // Compute the masked index: (hash + i + i * i) & mask. 6028 // Compute the masked index: (hash + i + i * i) & mask.
6028 __ movq(scratch, Operand(rsp, 2 * kPointerSize)); 6029 __ movq(scratch, StackOperandForArgument(2 * kPointerSize));
6029 if (i > 0) { 6030 if (i > 0) {
6030 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i))); 6031 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
6031 } 6032 }
6032 __ and_(scratch, Operand(rsp, 0)); 6033 __ and_(scratch, Operand(rsp, 0));
6033 6034
6034 // Scale the index by multiplying by the entry size. 6035 // Scale the index by multiplying by the entry size.
6035 ASSERT(NameDictionary::kEntrySize == 3); 6036 ASSERT(NameDictionary::kEntrySize == 3);
6036 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3. 6037 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3.
6037 6038
6038 // Having undefined at this place means the name is not contained. 6039 // Having undefined at this place means the name is not contained.
6039 __ movq(scratch, Operand(dictionary_, 6040 __ movq(scratch, Operand(dictionary_,
6040 index_, 6041 index_,
6041 times_pointer_size, 6042 times_pointer_size,
6042 kElementsStartOffset - kHeapObjectTag)); 6043 kElementsStartOffset - kHeapObjectTag));
6043 6044
6044 __ Cmp(scratch, masm->isolate()->factory()->undefined_value()); 6045 __ Cmp(scratch, masm->isolate()->factory()->undefined_value());
6045 __ j(equal, &not_in_dictionary); 6046 __ j(equal, &not_in_dictionary);
6046 6047
6047 // Stop if found the property. 6048 // Stop if found the property.
6048 __ cmpq(scratch, Operand(rsp, 3 * kPointerSize)); 6049 __ cmpq(scratch, StackOperandForArgument(3 * kPointerSize));
6049 __ j(equal, &in_dictionary); 6050 __ j(equal, &in_dictionary);
6050 6051
6051 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 6052 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
6052 // If we hit a key that is not a unique name during negative 6053 // If we hit a key that is not a unique name during negative
6053 // lookup we have to bailout as this key might be equal to the 6054 // lookup we have to bailout as this key might be equal to the
6054 // key we are looking for. 6055 // key we are looking for.
6055 6056
6056 // Check if the entry name is not a unique name. 6057 // Check if the entry name is not a unique name.
6057 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 6058 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
6058 __ JumpIfNotUniqueName(FieldOperand(scratch, Map::kInstanceTypeOffset), 6059 __ JumpIfNotUniqueName(FieldOperand(scratch, Map::kInstanceTypeOffset),
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
6390 // clobbers rbx, rdx, rdi 6391 // clobbers rbx, rdx, rdi
6391 // ----------------------------------- 6392 // -----------------------------------
6392 6393
6393 Label element_done; 6394 Label element_done;
6394 Label double_elements; 6395 Label double_elements;
6395 Label smi_element; 6396 Label smi_element;
6396 Label slow_elements; 6397 Label slow_elements;
6397 Label fast_elements; 6398 Label fast_elements;
6398 6399
6399 // Get array literal index, array literal and its map. 6400 // Get array literal index, array literal and its map.
6400 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); 6401 __ movq(rdx, StackOperandForArgument(1 * kPointerSize));
6401 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); 6402 __ movq(rbx, StackOperandForArgument(2 * kPointerSize));
6402 __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset)); 6403 __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
6403 6404
6404 __ CheckFastElements(rdi, &double_elements); 6405 __ CheckFastElements(rdi, &double_elements);
6405 6406
6406 // FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS 6407 // FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS
6407 __ JumpIfSmi(rax, &smi_element); 6408 __ JumpIfSmi(rax, &smi_element);
6408 __ CheckFastSmiElements(rdi, &fast_elements); 6409 __ CheckFastSmiElements(rdi, &fast_elements);
6409 6410
6410 // Store into the array literal requires a elements transition. Call into 6411 // Store into the array literal requires a elements transition. Call into
6411 // the runtime. 6412 // the runtime.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
6560 Handle<Object> undefined_sentinel( 6561 Handle<Object> undefined_sentinel(
6561 masm->isolate()->heap()->undefined_value(), 6562 masm->isolate()->heap()->undefined_value(),
6562 masm->isolate()); 6563 masm->isolate());
6563 6564
6564 // is the low bit set? If so, we are holey and that is good. 6565 // is the low bit set? If so, we are holey and that is good.
6565 __ testb(rdx, Immediate(1)); 6566 __ testb(rdx, Immediate(1));
6566 Label normal_sequence; 6567 Label normal_sequence;
6567 __ j(not_zero, &normal_sequence); 6568 __ j(not_zero, &normal_sequence);
6568 6569
6569 // look at the first argument 6570 // look at the first argument
6570 __ movq(rcx, Operand(rsp, kPointerSize)); 6571 __ movq(rcx, StackOperandForArgument(1 * kPointerSize));
6571 __ testq(rcx, rcx); 6572 __ testq(rcx, rcx);
6572 __ j(zero, &normal_sequence); 6573 __ j(zero, &normal_sequence);
6573 6574
6574 // We are going to create a holey array, but our kind is non-holey. 6575 // We are going to create a holey array, but our kind is non-holey.
6575 // Fix kind and retry (only if we have an allocation site in the cell). 6576 // Fix kind and retry (only if we have an allocation site in the cell).
6576 __ incl(rdx); 6577 __ incl(rdx);
6577 __ Cmp(rbx, undefined_sentinel); 6578 __ Cmp(rbx, undefined_sentinel);
6578 __ j(equal, &normal_sequence); 6579 __ j(equal, &normal_sequence);
6579 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); 6580 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
6580 Handle<Map> allocation_site_map( 6581 Handle<Map> allocation_site_map(
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
6739 InternalArrayNoArgumentConstructorStub stub0(kind); 6740 InternalArrayNoArgumentConstructorStub stub0(kind);
6740 __ TailCallStub(&stub0); 6741 __ TailCallStub(&stub0);
6741 6742
6742 __ bind(&not_zero_case); 6743 __ bind(&not_zero_case);
6743 __ cmpl(rax, Immediate(1)); 6744 __ cmpl(rax, Immediate(1));
6744 __ j(greater, &not_one_case); 6745 __ j(greater, &not_one_case);
6745 6746
6746 if (IsFastPackedElementsKind(kind)) { 6747 if (IsFastPackedElementsKind(kind)) {
6747 // We might need to create a holey array 6748 // We might need to create a holey array
6748 // look at the first argument 6749 // look at the first argument
6749 __ movq(rcx, Operand(rsp, kPointerSize)); 6750 __ movq(rcx, StackOperandForArgument(1 * kPointerSize));
6750 __ testq(rcx, rcx); 6751 __ testq(rcx, rcx);
6751 __ j(zero, &normal_sequence); 6752 __ j(zero, &normal_sequence);
6752 6753
6753 InternalArraySingleArgumentConstructorStub 6754 InternalArraySingleArgumentConstructorStub
6754 stub1_holey(GetHoleyElementsKind(kind)); 6755 stub1_holey(GetHoleyElementsKind(kind));
6755 __ TailCallStub(&stub1_holey); 6756 __ TailCallStub(&stub1_holey);
6756 } 6757 }
6757 6758
6758 __ bind(&normal_sequence); 6759 __ bind(&normal_sequence);
6759 InternalArraySingleArgumentConstructorStub stub1(kind); 6760 InternalArraySingleArgumentConstructorStub stub1(kind);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
6816 __ bind(&fast_elements_case); 6817 __ bind(&fast_elements_case);
6817 GenerateCase(masm, FAST_ELEMENTS); 6818 GenerateCase(masm, FAST_ELEMENTS);
6818 } 6819 }
6819 6820
6820 6821
6821 #undef __ 6822 #undef __
6822 6823
6823 } } // namespace v8::internal 6824 } } // namespace v8::internal
6824 6825
6825 #endif // V8_TARGET_ARCH_X64 6826 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698