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

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

Issue 153913002: A64: Synchronize with r16756. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/codegen-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 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 // are about to return. 977 // are about to return.
978 if (op == Token::SHR) { 978 if (op == Token::SHR) {
979 __ mov(Operand(esp, 1 * kPointerSize), left); 979 __ mov(Operand(esp, 1 * kPointerSize), left);
980 __ mov(Operand(esp, 2 * kPointerSize), Immediate(0)); 980 __ mov(Operand(esp, 2 * kPointerSize), Immediate(0));
981 __ fild_d(Operand(esp, 1 * kPointerSize)); 981 __ fild_d(Operand(esp, 1 * kPointerSize));
982 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 982 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
983 } else { 983 } else {
984 ASSERT_EQ(Token::SHL, op); 984 ASSERT_EQ(Token::SHL, op);
985 if (CpuFeatures::IsSupported(SSE2)) { 985 if (CpuFeatures::IsSupported(SSE2)) {
986 CpuFeatureScope use_sse2(masm, SSE2); 986 CpuFeatureScope use_sse2(masm, SSE2);
987 __ cvtsi2sd(xmm0, left); 987 __ Cvtsi2sd(xmm0, left);
988 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 988 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
989 } else { 989 } else {
990 __ mov(Operand(esp, 1 * kPointerSize), left); 990 __ mov(Operand(esp, 1 * kPointerSize), left);
991 __ fild_s(Operand(esp, 1 * kPointerSize)); 991 __ fild_s(Operand(esp, 1 * kPointerSize));
992 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 992 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
993 } 993 }
994 } 994 }
995 __ ret(2 * kPointerSize); 995 __ ret(2 * kPointerSize);
996 break; 996 break;
997 } 997 }
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 // Fall through! 1363 // Fall through!
1364 case NO_OVERWRITE: 1364 case NO_OVERWRITE:
1365 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 1365 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
1366 __ bind(&skip_allocation); 1366 __ bind(&skip_allocation);
1367 break; 1367 break;
1368 default: UNREACHABLE(); 1368 default: UNREACHABLE();
1369 } 1369 }
1370 // Store the result in the HeapNumber and return. 1370 // Store the result in the HeapNumber and return.
1371 if (CpuFeatures::IsSupported(SSE2)) { 1371 if (CpuFeatures::IsSupported(SSE2)) {
1372 CpuFeatureScope use_sse2(masm, SSE2); 1372 CpuFeatureScope use_sse2(masm, SSE2);
1373 __ cvtsi2sd(xmm0, ebx); 1373 __ Cvtsi2sd(xmm0, ebx);
1374 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 1374 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
1375 } else { 1375 } else {
1376 __ mov(Operand(esp, 1 * kPointerSize), ebx); 1376 __ mov(Operand(esp, 1 * kPointerSize), ebx);
1377 __ fild_s(Operand(esp, 1 * kPointerSize)); 1377 __ fild_s(Operand(esp, 1 * kPointerSize));
1378 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 1378 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
1379 } 1379 }
1380 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack. 1380 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack.
1381 } 1381 }
1382 1382
1383 __ bind(&not_floats); 1383 __ bind(&not_floats);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 // Fall through! 1587 // Fall through!
1588 case NO_OVERWRITE: 1588 case NO_OVERWRITE:
1589 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 1589 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
1590 __ bind(&skip_allocation); 1590 __ bind(&skip_allocation);
1591 break; 1591 break;
1592 default: UNREACHABLE(); 1592 default: UNREACHABLE();
1593 } 1593 }
1594 // Store the result in the HeapNumber and return. 1594 // Store the result in the HeapNumber and return.
1595 if (CpuFeatures::IsSupported(SSE2)) { 1595 if (CpuFeatures::IsSupported(SSE2)) {
1596 CpuFeatureScope use_sse2(masm, SSE2); 1596 CpuFeatureScope use_sse2(masm, SSE2);
1597 __ cvtsi2sd(xmm0, ebx); 1597 __ Cvtsi2sd(xmm0, ebx);
1598 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 1598 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
1599 } else { 1599 } else {
1600 __ mov(Operand(esp, 1 * kPointerSize), ebx); 1600 __ mov(Operand(esp, 1 * kPointerSize), ebx);
1601 __ fild_s(Operand(esp, 1 * kPointerSize)); 1601 __ fild_s(Operand(esp, 1 * kPointerSize));
1602 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 1602 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
1603 } 1603 }
1604 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack. 1604 __ ret(2 * kPointerSize); // Drop two pushed arguments from the stack.
1605 } 1605 }
1606 1606
1607 __ bind(&not_floats); 1607 __ bind(&not_floats);
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 // Fall through! 1775 // Fall through!
1776 case NO_OVERWRITE: 1776 case NO_OVERWRITE:
1777 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 1777 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
1778 __ bind(&skip_allocation); 1778 __ bind(&skip_allocation);
1779 break; 1779 break;
1780 default: UNREACHABLE(); 1780 default: UNREACHABLE();
1781 } 1781 }
1782 // Store the result in the HeapNumber and return. 1782 // Store the result in the HeapNumber and return.
1783 if (CpuFeatures::IsSupported(SSE2)) { 1783 if (CpuFeatures::IsSupported(SSE2)) {
1784 CpuFeatureScope use_sse2(masm, SSE2); 1784 CpuFeatureScope use_sse2(masm, SSE2);
1785 __ cvtsi2sd(xmm0, ebx); 1785 __ Cvtsi2sd(xmm0, ebx);
1786 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 1786 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
1787 } else { 1787 } else {
1788 __ mov(Operand(esp, 1 * kPointerSize), ebx); 1788 __ mov(Operand(esp, 1 * kPointerSize), ebx);
1789 __ fild_s(Operand(esp, 1 * kPointerSize)); 1789 __ fild_s(Operand(esp, 1 * kPointerSize));
1790 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 1790 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
1791 } 1791 }
1792 __ ret(2 * kPointerSize); 1792 __ ret(2 * kPointerSize);
1793 } 1793 }
1794 break; 1794 break;
1795 } 1795 }
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 __ j(not_equal, not_numbers); // Argument in edx is not a number. 2322 __ j(not_equal, not_numbers); // Argument in edx is not a number.
2323 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 2323 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
2324 __ bind(&load_eax); 2324 __ bind(&load_eax);
2325 // Load operand in eax into xmm1, or branch to not_numbers. 2325 // Load operand in eax into xmm1, or branch to not_numbers.
2326 __ JumpIfSmi(eax, &load_smi_eax, Label::kNear); 2326 __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
2327 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map()); 2327 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
2328 __ j(equal, &load_float_eax, Label::kNear); 2328 __ j(equal, &load_float_eax, Label::kNear);
2329 __ jmp(not_numbers); // Argument in eax is not a number. 2329 __ jmp(not_numbers); // Argument in eax is not a number.
2330 __ bind(&load_smi_edx); 2330 __ bind(&load_smi_edx);
2331 __ SmiUntag(edx); // Untag smi before converting to float. 2331 __ SmiUntag(edx); // Untag smi before converting to float.
2332 __ cvtsi2sd(xmm0, edx); 2332 __ Cvtsi2sd(xmm0, edx);
2333 __ SmiTag(edx); // Retag smi for heap number overwriting test. 2333 __ SmiTag(edx); // Retag smi for heap number overwriting test.
2334 __ jmp(&load_eax); 2334 __ jmp(&load_eax);
2335 __ bind(&load_smi_eax); 2335 __ bind(&load_smi_eax);
2336 __ SmiUntag(eax); // Untag smi before converting to float. 2336 __ SmiUntag(eax); // Untag smi before converting to float.
2337 __ cvtsi2sd(xmm1, eax); 2337 __ Cvtsi2sd(xmm1, eax);
2338 __ SmiTag(eax); // Retag smi for heap number overwriting test. 2338 __ SmiTag(eax); // Retag smi for heap number overwriting test.
2339 __ jmp(&done, Label::kNear); 2339 __ jmp(&done, Label::kNear);
2340 __ bind(&load_float_eax); 2340 __ bind(&load_float_eax);
2341 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 2341 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
2342 __ bind(&done); 2342 __ bind(&done);
2343 } 2343 }
2344 2344
2345 2345
2346 void FloatingPointHelper::LoadSSE2Smis(MacroAssembler* masm, 2346 void FloatingPointHelper::LoadSSE2Smis(MacroAssembler* masm,
2347 Register scratch) { 2347 Register scratch) {
2348 const Register left = edx; 2348 const Register left = edx;
2349 const Register right = eax; 2349 const Register right = eax;
2350 __ mov(scratch, left); 2350 __ mov(scratch, left);
2351 ASSERT(!scratch.is(right)); // We're about to clobber scratch. 2351 ASSERT(!scratch.is(right)); // We're about to clobber scratch.
2352 __ SmiUntag(scratch); 2352 __ SmiUntag(scratch);
2353 __ cvtsi2sd(xmm0, scratch); 2353 __ Cvtsi2sd(xmm0, scratch);
2354 2354
2355 __ mov(scratch, right); 2355 __ mov(scratch, right);
2356 __ SmiUntag(scratch); 2356 __ SmiUntag(scratch);
2357 __ cvtsi2sd(xmm1, scratch); 2357 __ Cvtsi2sd(xmm1, scratch);
2358 } 2358 }
2359 2359
2360 2360
2361 void FloatingPointHelper::CheckSSE2OperandIsInt32(MacroAssembler* masm, 2361 void FloatingPointHelper::CheckSSE2OperandIsInt32(MacroAssembler* masm,
2362 Label* non_int32, 2362 Label* non_int32,
2363 XMMRegister operand, 2363 XMMRegister operand,
2364 Register int32_result, 2364 Register int32_result,
2365 Register scratch, 2365 Register scratch,
2366 XMMRegister xmm_scratch) { 2366 XMMRegister xmm_scratch) {
2367 __ cvttsd2si(int32_result, Operand(operand)); 2367 __ cvttsd2si(int32_result, Operand(operand));
2368 __ cvtsi2sd(xmm_scratch, int32_result); 2368 __ Cvtsi2sd(xmm_scratch, int32_result);
2369 __ pcmpeqd(xmm_scratch, operand); 2369 __ pcmpeqd(xmm_scratch, operand);
2370 __ movmskps(scratch, xmm_scratch); 2370 __ movmskps(scratch, xmm_scratch);
2371 // Two least significant bits should be both set. 2371 // Two least significant bits should be both set.
2372 __ not_(scratch); 2372 __ not_(scratch);
2373 __ test(scratch, Immediate(3)); 2373 __ test(scratch, Immediate(3));
2374 __ j(not_zero, non_int32); 2374 __ j(not_zero, non_int32);
2375 } 2375 }
2376 2376
2377 2377
2378 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, 2378 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2463 const Register scratch = ecx; 2463 const Register scratch = ecx;
2464 const XMMRegister double_result = xmm3; 2464 const XMMRegister double_result = xmm3;
2465 const XMMRegister double_base = xmm2; 2465 const XMMRegister double_base = xmm2;
2466 const XMMRegister double_exponent = xmm1; 2466 const XMMRegister double_exponent = xmm1;
2467 const XMMRegister double_scratch = xmm4; 2467 const XMMRegister double_scratch = xmm4;
2468 2468
2469 Label call_runtime, done, exponent_not_smi, int_exponent; 2469 Label call_runtime, done, exponent_not_smi, int_exponent;
2470 2470
2471 // Save 1 in double_result - we need this several times later on. 2471 // Save 1 in double_result - we need this several times later on.
2472 __ mov(scratch, Immediate(1)); 2472 __ mov(scratch, Immediate(1));
2473 __ cvtsi2sd(double_result, scratch); 2473 __ Cvtsi2sd(double_result, scratch);
2474 2474
2475 if (exponent_type_ == ON_STACK) { 2475 if (exponent_type_ == ON_STACK) {
2476 Label base_is_smi, unpack_exponent; 2476 Label base_is_smi, unpack_exponent;
2477 // The exponent and base are supplied as arguments on the stack. 2477 // The exponent and base are supplied as arguments on the stack.
2478 // This can only happen if the stub is called from non-optimized code. 2478 // This can only happen if the stub is called from non-optimized code.
2479 // Load input parameters from stack. 2479 // Load input parameters from stack.
2480 __ mov(base, Operand(esp, 2 * kPointerSize)); 2480 __ mov(base, Operand(esp, 2 * kPointerSize));
2481 __ mov(exponent, Operand(esp, 1 * kPointerSize)); 2481 __ mov(exponent, Operand(esp, 1 * kPointerSize));
2482 2482
2483 __ JumpIfSmi(base, &base_is_smi, Label::kNear); 2483 __ JumpIfSmi(base, &base_is_smi, Label::kNear);
2484 __ cmp(FieldOperand(base, HeapObject::kMapOffset), 2484 __ cmp(FieldOperand(base, HeapObject::kMapOffset),
2485 factory->heap_number_map()); 2485 factory->heap_number_map());
2486 __ j(not_equal, &call_runtime); 2486 __ j(not_equal, &call_runtime);
2487 2487
2488 __ movdbl(double_base, FieldOperand(base, HeapNumber::kValueOffset)); 2488 __ movdbl(double_base, FieldOperand(base, HeapNumber::kValueOffset));
2489 __ jmp(&unpack_exponent, Label::kNear); 2489 __ jmp(&unpack_exponent, Label::kNear);
2490 2490
2491 __ bind(&base_is_smi); 2491 __ bind(&base_is_smi);
2492 __ SmiUntag(base); 2492 __ SmiUntag(base);
2493 __ cvtsi2sd(double_base, base); 2493 __ Cvtsi2sd(double_base, base);
2494 2494
2495 __ bind(&unpack_exponent); 2495 __ bind(&unpack_exponent);
2496 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 2496 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
2497 __ SmiUntag(exponent); 2497 __ SmiUntag(exponent);
2498 __ jmp(&int_exponent); 2498 __ jmp(&int_exponent);
2499 2499
2500 __ bind(&exponent_not_smi); 2500 __ bind(&exponent_not_smi);
2501 __ cmp(FieldOperand(exponent, HeapObject::kMapOffset), 2501 __ cmp(FieldOperand(exponent, HeapObject::kMapOffset),
2502 factory->heap_number_map()); 2502 factory->heap_number_map());
2503 __ j(not_equal, &call_runtime); 2503 __ j(not_equal, &call_runtime);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 __ divsd(double_scratch2, double_result); 2676 __ divsd(double_scratch2, double_result);
2677 __ movsd(double_result, double_scratch2); 2677 __ movsd(double_result, double_scratch2);
2678 // Test whether result is zero. Bail out to check for subnormal result. 2678 // Test whether result is zero. Bail out to check for subnormal result.
2679 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. 2679 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
2680 __ xorps(double_scratch2, double_scratch2); 2680 __ xorps(double_scratch2, double_scratch2);
2681 __ ucomisd(double_scratch2, double_result); // Result cannot be NaN. 2681 __ ucomisd(double_scratch2, double_result); // Result cannot be NaN.
2682 // double_exponent aliased as double_scratch2 has already been overwritten 2682 // double_exponent aliased as double_scratch2 has already been overwritten
2683 // and may not have contained the exponent value in the first place when the 2683 // and may not have contained the exponent value in the first place when the
2684 // exponent is a smi. We reset it with exponent value before bailing out. 2684 // exponent is a smi. We reset it with exponent value before bailing out.
2685 __ j(not_equal, &done); 2685 __ j(not_equal, &done);
2686 __ cvtsi2sd(double_exponent, exponent); 2686 __ Cvtsi2sd(double_exponent, exponent);
2687 2687
2688 // Returning or bailing out. 2688 // Returning or bailing out.
2689 Counters* counters = masm->isolate()->counters(); 2689 Counters* counters = masm->isolate()->counters();
2690 if (exponent_type_ == ON_STACK) { 2690 if (exponent_type_ == ON_STACK) {
2691 // The arguments are still on the stack. 2691 // The arguments are still on the stack.
2692 __ bind(&call_runtime); 2692 __ bind(&call_runtime);
2693 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); 2693 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
2694 2694
2695 // The stub is called from non-optimized code, which expects the result 2695 // The stub is called from non-optimized code, which expects the result
2696 // as heap number in exponent. 2696 // as heap number in exponent.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2749 // -- edx : receiver 2749 // -- edx : receiver
2750 // -- esp[0] : return address 2750 // -- esp[0] : return address
2751 // ----------------------------------- 2751 // -----------------------------------
2752 Label miss; 2752 Label miss;
2753 2753
2754 if (kind() == Code::KEYED_LOAD_IC) { 2754 if (kind() == Code::KEYED_LOAD_IC) {
2755 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string())); 2755 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string()));
2756 __ j(not_equal, &miss); 2756 __ j(not_equal, &miss);
2757 } 2757 }
2758 2758
2759 StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss, 2759 StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss);
2760 support_wrapper_);
2761 __ bind(&miss); 2760 __ bind(&miss);
2762 StubCompiler::TailCallBuiltin( 2761 StubCompiler::TailCallBuiltin(
2763 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); 2762 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
2764 } 2763 }
2765 2764
2766 2765
2767 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { 2766 void StoreArrayLengthStub::Generate(MacroAssembler* masm) {
2768 // ----------- S t a t e ------------- 2767 // ----------- S t a t e -------------
2769 // -- eax : value 2768 // -- eax : value
2770 // -- ecx : name 2769 // -- ecx : name
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after
4501 if (FLAG_debug_code) { 4500 if (FLAG_debug_code) {
4502 __ CheckStackAlignment(); 4501 __ CheckStackAlignment();
4503 } 4502 }
4504 4503
4505 if (do_gc) { 4504 if (do_gc) {
4506 // Pass failure code returned from last attempt as first argument to 4505 // Pass failure code returned from last attempt as first argument to
4507 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the 4506 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
4508 // stack alignment is known to be correct. This function takes one argument 4507 // stack alignment is known to be correct. This function takes one argument
4509 // which is passed on the stack, and we know that the stack has been 4508 // which is passed on the stack, and we know that the stack has been
4510 // prepared to pass at least one argument. 4509 // prepared to pass at least one argument.
4510 __ mov(Operand(esp, 1 * kPointerSize),
4511 Immediate(ExternalReference::isolate_address(masm->isolate())));
4511 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result. 4512 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result.
4512 __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY); 4513 __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY);
4513 } 4514 }
4514 4515
4515 ExternalReference scope_depth = 4516 ExternalReference scope_depth =
4516 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); 4517 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
4517 if (always_allocate_scope) { 4518 if (always_allocate_scope) {
4518 __ inc(Operand::StaticVariable(scope_depth)); 4519 __ inc(Operand::StaticVariable(scope_depth));
4519 } 4520 }
4520 4521
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
5508 Register scratch2, 5509 Register scratch2,
5509 Register scratch3, 5510 Register scratch3,
5510 Label* slow) { 5511 Label* slow) {
5511 // First check if the argument is already a string. 5512 // First check if the argument is already a string.
5512 Label not_string, done; 5513 Label not_string, done;
5513 __ JumpIfSmi(arg, &not_string); 5514 __ JumpIfSmi(arg, &not_string);
5514 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); 5515 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
5515 __ j(below, &done); 5516 __ j(below, &done);
5516 5517
5517 // Check the number to string cache. 5518 // Check the number to string cache.
5518 Label not_cached;
5519 __ bind(&not_string); 5519 __ bind(&not_string);
5520 // Puts the cached result into scratch1. 5520 // Puts the cached result into scratch1.
5521 NumberToStringStub::GenerateLookupNumberStringCache(masm, 5521 NumberToStringStub::GenerateLookupNumberStringCache(masm,
5522 arg, 5522 arg,
5523 scratch1, 5523 scratch1,
5524 scratch2, 5524 scratch2,
5525 scratch3, 5525 scratch3,
5526 &not_cached); 5526 slow);
5527 __ mov(arg, scratch1); 5527 __ mov(arg, scratch1);
5528 __ mov(Operand(esp, stack_offset), arg); 5528 __ mov(Operand(esp, stack_offset), arg);
5529 __ jmp(&done);
5530
5531 // Check if the argument is a safe string wrapper.
5532 __ bind(&not_cached);
5533 __ JumpIfSmi(arg, slow);
5534 __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1.
5535 __ j(not_equal, slow);
5536 __ test_b(FieldOperand(scratch1, Map::kBitField2Offset),
5537 1 << Map::kStringWrapperSafeForDefaultValueOf);
5538 __ j(zero, slow);
5539 __ mov(arg, FieldOperand(arg, JSValue::kValueOffset));
5540 __ mov(Operand(esp, stack_offset), arg);
5541
5542 __ bind(&done); 5529 __ bind(&done);
5543 } 5530 }
5544 5531
5545 5532
5546 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, 5533 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
5547 Register dest, 5534 Register dest,
5548 Register src, 5535 Register src,
5549 Register count, 5536 Register count,
5550 Register scratch, 5537 Register scratch,
5551 bool ascii) { 5538 bool ascii) {
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
6265 Label done, left, left_smi, right_smi; 6252 Label done, left, left_smi, right_smi;
6266 __ JumpIfSmi(eax, &right_smi, Label::kNear); 6253 __ JumpIfSmi(eax, &right_smi, Label::kNear);
6267 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 6254 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
6268 masm->isolate()->factory()->heap_number_map()); 6255 masm->isolate()->factory()->heap_number_map());
6269 __ j(not_equal, &maybe_undefined1, Label::kNear); 6256 __ j(not_equal, &maybe_undefined1, Label::kNear);
6270 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 6257 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
6271 __ jmp(&left, Label::kNear); 6258 __ jmp(&left, Label::kNear);
6272 __ bind(&right_smi); 6259 __ bind(&right_smi);
6273 __ mov(ecx, eax); // Can't clobber eax because we can still jump away. 6260 __ mov(ecx, eax); // Can't clobber eax because we can still jump away.
6274 __ SmiUntag(ecx); 6261 __ SmiUntag(ecx);
6275 __ cvtsi2sd(xmm1, ecx); 6262 __ Cvtsi2sd(xmm1, ecx);
6276 6263
6277 __ bind(&left); 6264 __ bind(&left);
6278 __ JumpIfSmi(edx, &left_smi, Label::kNear); 6265 __ JumpIfSmi(edx, &left_smi, Label::kNear);
6279 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 6266 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
6280 masm->isolate()->factory()->heap_number_map()); 6267 masm->isolate()->factory()->heap_number_map());
6281 __ j(not_equal, &maybe_undefined2, Label::kNear); 6268 __ j(not_equal, &maybe_undefined2, Label::kNear);
6282 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 6269 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
6283 __ jmp(&done); 6270 __ jmp(&done);
6284 __ bind(&left_smi); 6271 __ bind(&left_smi);
6285 __ mov(ecx, edx); // Can't clobber edx because we can still jump away. 6272 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
6286 __ SmiUntag(ecx); 6273 __ SmiUntag(ecx);
6287 __ cvtsi2sd(xmm0, ecx); 6274 __ Cvtsi2sd(xmm0, ecx);
6288 6275
6289 __ bind(&done); 6276 __ bind(&done);
6290 // Compare operands. 6277 // Compare operands.
6291 __ ucomisd(xmm0, xmm1); 6278 __ ucomisd(xmm0, xmm1);
6292 6279
6293 // Don't base result on EFLAGS when a NaN is involved. 6280 // Don't base result on EFLAGS when a NaN is involved.
6294 __ j(parity_even, &unordered, Label::kNear); 6281 __ j(parity_even, &unordered, Label::kNear);
6295 6282
6296 // Return a result of -1, 0, or 1, based on EFLAGS. 6283 // Return a result of -1, 0, or 1, based on EFLAGS.
6297 // Performing mov, because xor would destroy the flag register. 6284 // Performing mov, because xor would destroy the flag register.
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after
7232 // Restore ecx. 7219 // Restore ecx.
7233 __ pop(edx); 7220 __ pop(edx);
7234 __ pop(ecx); 7221 __ pop(ecx);
7235 __ pop(eax); 7222 __ pop(eax);
7236 7223
7237 __ ret(0); 7224 __ ret(0);
7238 } 7225 }
7239 7226
7240 7227
7241 template<class T> 7228 template<class T>
7242 static void CreateArrayDispatch(MacroAssembler* masm) { 7229 static void CreateArrayDispatch(MacroAssembler* masm,
7243 int last_index = GetSequenceIndexFromFastElementsKind( 7230 AllocationSiteOverrideMode mode) {
7244 TERMINAL_FAST_ELEMENTS_KIND); 7231 if (mode == DISABLE_ALLOCATION_SITES) {
7245 for (int i = 0; i <= last_index; ++i) { 7232 T stub(GetInitialFastElementsKind(),
7246 Label next; 7233 CONTEXT_CHECK_REQUIRED,
7247 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 7234 mode);
7248 __ cmp(edx, kind);
7249 __ j(not_equal, &next);
7250 T stub(kind);
7251 __ TailCallStub(&stub); 7235 __ TailCallStub(&stub);
7252 __ bind(&next); 7236 } else if (mode == DONT_OVERRIDE) {
7237 int last_index = GetSequenceIndexFromFastElementsKind(
7238 TERMINAL_FAST_ELEMENTS_KIND);
7239 for (int i = 0; i <= last_index; ++i) {
7240 Label next;
7241 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7242 __ cmp(edx, kind);
7243 __ j(not_equal, &next);
7244 T stub(kind);
7245 __ TailCallStub(&stub);
7246 __ bind(&next);
7247 }
7248
7249 // If we reached this point there is a problem.
7250 __ Abort(kUnexpectedElementsKindInArrayConstructor);
7251 } else {
7252 UNREACHABLE();
7253 } 7253 }
7254
7255 // If we reached this point there is a problem.
7256 __ Abort(kUnexpectedElementsKindInArrayConstructor);
7257 } 7254 }
7258 7255
7259 7256
7260 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { 7257 static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
7261 // ebx - type info cell 7258 AllocationSiteOverrideMode mode) {
7262 // edx - kind 7259 // ebx - type info cell (if mode != DISABLE_ALLOCATION_SITES)
7260 // edx - kind (if mode != DISABLE_ALLOCATION_SITES)
7263 // eax - number of arguments 7261 // eax - number of arguments
7264 // edi - constructor? 7262 // edi - constructor?
7265 // esp[0] - return address 7263 // esp[0] - return address
7266 // esp[4] - last argument 7264 // esp[4] - last argument
7267 ASSERT(FAST_SMI_ELEMENTS == 0); 7265 Label normal_sequence;
7268 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 7266 if (mode == DONT_OVERRIDE) {
7269 ASSERT(FAST_ELEMENTS == 2); 7267 ASSERT(FAST_SMI_ELEMENTS == 0);
7270 ASSERT(FAST_HOLEY_ELEMENTS == 3); 7268 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
7271 ASSERT(FAST_DOUBLE_ELEMENTS == 4); 7269 ASSERT(FAST_ELEMENTS == 2);
7272 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); 7270 ASSERT(FAST_HOLEY_ELEMENTS == 3);
7271 ASSERT(FAST_DOUBLE_ELEMENTS == 4);
7272 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
7273 7273
7274 Handle<Object> undefined_sentinel( 7274 // is the low bit set? If so, we are holey and that is good.
7275 masm->isolate()->heap()->undefined_value(), 7275 __ test_b(edx, 1);
7276 masm->isolate()); 7276 __ j(not_zero, &normal_sequence);
7277 7277 }
7278 // is the low bit set? If so, we are holey and that is good.
7279 __ test_b(edx, 1);
7280 Label normal_sequence;
7281 __ j(not_zero, &normal_sequence);
7282 7278
7283 // look at the first argument 7279 // look at the first argument
7284 __ mov(ecx, Operand(esp, kPointerSize)); 7280 __ mov(ecx, Operand(esp, kPointerSize));
7285 __ test(ecx, ecx); 7281 __ test(ecx, ecx);
7286 __ j(zero, &normal_sequence); 7282 __ j(zero, &normal_sequence);
7287 7283
7288 // We are going to create a holey array, but our kind is non-holey. 7284 if (mode == DISABLE_ALLOCATION_SITES) {
7289 // Fix kind and retry (only if we have an allocation site in the cell). 7285 ElementsKind initial = GetInitialFastElementsKind();
7290 __ inc(edx); 7286 ElementsKind holey_initial = GetHoleyElementsKind(initial);
7291 __ cmp(ebx, Immediate(undefined_sentinel));
7292 __ j(equal, &normal_sequence);
7293 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset));
7294 Handle<Map> allocation_site_map(
7295 masm->isolate()->heap()->allocation_site_map(),
7296 masm->isolate());
7297 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
7298 __ j(not_equal, &normal_sequence);
7299 7287
7300 // Save the resulting elements kind in type info 7288 ArraySingleArgumentConstructorStub stub_holey(holey_initial,
7301 __ SmiTag(edx); 7289 CONTEXT_CHECK_REQUIRED,
7302 __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx); 7290 DISABLE_ALLOCATION_SITES);
7303 __ SmiUntag(edx); 7291 __ TailCallStub(&stub_holey);
7304 7292
7305 __ bind(&normal_sequence); 7293 __ bind(&normal_sequence);
7306 int last_index = GetSequenceIndexFromFastElementsKind( 7294 ArraySingleArgumentConstructorStub stub(initial,
7307 TERMINAL_FAST_ELEMENTS_KIND); 7295 CONTEXT_CHECK_REQUIRED,
7308 for (int i = 0; i <= last_index; ++i) { 7296 DISABLE_ALLOCATION_SITES);
7309 Label next;
7310 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7311 __ cmp(edx, kind);
7312 __ j(not_equal, &next);
7313 ArraySingleArgumentConstructorStub stub(kind);
7314 __ TailCallStub(&stub); 7297 __ TailCallStub(&stub);
7315 __ bind(&next); 7298 } else if (mode == DONT_OVERRIDE) {
7299 // We are going to create a holey array, but our kind is non-holey.
7300 // Fix kind and retry.
7301 __ inc(edx);
7302 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset));
7303 if (FLAG_debug_code) {
7304 Handle<Map> allocation_site_map(
7305 masm->isolate()->heap()->allocation_site_map(),
7306 masm->isolate());
7307 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
7308 __ Assert(equal, kExpectedAllocationSiteInCell);
7309 }
7310
7311 // Save the resulting elements kind in type info
7312 __ SmiTag(edx);
7313 __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx);
7314 __ SmiUntag(edx);
7315
7316 __ bind(&normal_sequence);
7317 int last_index = GetSequenceIndexFromFastElementsKind(
7318 TERMINAL_FAST_ELEMENTS_KIND);
7319 for (int i = 0; i <= last_index; ++i) {
7320 Label next;
7321 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7322 __ cmp(edx, kind);
7323 __ j(not_equal, &next);
7324 ArraySingleArgumentConstructorStub stub(kind);
7325 __ TailCallStub(&stub);
7326 __ bind(&next);
7327 }
7328
7329 // If we reached this point there is a problem.
7330 __ Abort(kUnexpectedElementsKindInArrayConstructor);
7331 } else {
7332 UNREACHABLE();
7316 } 7333 }
7317
7318 // If we reached this point there is a problem.
7319 __ Abort(kUnexpectedElementsKindInArrayConstructor);
7320 } 7334 }
7321 7335
7322 7336
7323 template<class T> 7337 template<class T>
7324 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { 7338 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
7339 ElementsKind initial_kind = GetInitialFastElementsKind();
7340 ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
7341
7325 int to_index = GetSequenceIndexFromFastElementsKind( 7342 int to_index = GetSequenceIndexFromFastElementsKind(
7326 TERMINAL_FAST_ELEMENTS_KIND); 7343 TERMINAL_FAST_ELEMENTS_KIND);
7327 for (int i = 0; i <= to_index; ++i) { 7344 for (int i = 0; i <= to_index; ++i) {
7328 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 7345 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7329 T stub(kind); 7346 T stub(kind);
7330 stub.GetCode(isolate)->set_is_pregenerated(true); 7347 stub.GetCode(isolate)->set_is_pregenerated(true);
7331 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { 7348 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
7349 (!FLAG_track_allocation_sites &&
7350 (kind == initial_kind || kind == initial_holey_kind))) {
7332 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); 7351 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
7333 stub1.GetCode(isolate)->set_is_pregenerated(true); 7352 stub1.GetCode(isolate)->set_is_pregenerated(true);
7334 } 7353 }
7335 } 7354 }
7336 } 7355 }
7337 7356
7338 7357
7339 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 7358 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
7340 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 7359 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
7341 isolate); 7360 isolate);
(...skipping 12 matching lines...) Expand all
7354 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); 7373 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
7355 stubh1.GetCode(isolate)->set_is_pregenerated(true); 7374 stubh1.GetCode(isolate)->set_is_pregenerated(true);
7356 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); 7375 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
7357 stubh2.GetCode(isolate)->set_is_pregenerated(true); 7376 stubh2.GetCode(isolate)->set_is_pregenerated(true);
7358 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); 7377 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
7359 stubh3.GetCode(isolate)->set_is_pregenerated(true); 7378 stubh3.GetCode(isolate)->set_is_pregenerated(true);
7360 } 7379 }
7361 } 7380 }
7362 7381
7363 7382
7383 void ArrayConstructorStub::GenerateDispatchToArrayStub(
7384 MacroAssembler* masm,
7385 AllocationSiteOverrideMode mode) {
7386 if (argument_count_ == ANY) {
7387 Label not_zero_case, not_one_case;
7388 __ test(eax, eax);
7389 __ j(not_zero, &not_zero_case);
7390 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
7391
7392 __ bind(&not_zero_case);
7393 __ cmp(eax, 1);
7394 __ j(greater, &not_one_case);
7395 CreateArrayDispatchOneArgument(masm, mode);
7396
7397 __ bind(&not_one_case);
7398 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
7399 } else if (argument_count_ == NONE) {
7400 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
7401 } else if (argument_count_ == ONE) {
7402 CreateArrayDispatchOneArgument(masm, mode);
7403 } else if (argument_count_ == MORE_THAN_ONE) {
7404 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
7405 } else {
7406 UNREACHABLE();
7407 }
7408 }
7409
7410
7364 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 7411 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
7365 // ----------- S t a t e ------------- 7412 // ----------- S t a t e -------------
7366 // -- eax : argc (only if argument_count_ == ANY) 7413 // -- eax : argc (only if argument_count_ == ANY)
7367 // -- ebx : type info cell 7414 // -- ebx : type info cell
7368 // -- edi : constructor 7415 // -- edi : constructor
7369 // -- esp[0] : return address 7416 // -- esp[0] : return address
7370 // -- esp[4] : last argument 7417 // -- esp[4] : last argument
7371 // ----------------------------------- 7418 // -----------------------------------
7372 Handle<Object> undefined_sentinel( 7419 Handle<Object> undefined_sentinel(
7373 masm->isolate()->heap()->undefined_value(), 7420 masm->isolate()->heap()->undefined_value(),
(...skipping 14 matching lines...) Expand all
7388 // We should either have undefined in ebx or a valid cell 7435 // We should either have undefined in ebx or a valid cell
7389 Label okay_here; 7436 Label okay_here;
7390 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); 7437 Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
7391 __ cmp(ebx, Immediate(undefined_sentinel)); 7438 __ cmp(ebx, Immediate(undefined_sentinel));
7392 __ j(equal, &okay_here); 7439 __ j(equal, &okay_here);
7393 __ cmp(FieldOperand(ebx, 0), Immediate(cell_map)); 7440 __ cmp(FieldOperand(ebx, 0), Immediate(cell_map));
7394 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); 7441 __ Assert(equal, kExpectedPropertyCellInRegisterEbx);
7395 __ bind(&okay_here); 7442 __ bind(&okay_here);
7396 } 7443 }
7397 7444
7398 Label no_info, switch_ready; 7445 Label no_info;
7399 // Get the elements kind and case on that. 7446 // If the type cell is undefined, or contains anything other than an
7447 // AllocationSite, call an array constructor that doesn't use AllocationSites.
7400 __ cmp(ebx, Immediate(undefined_sentinel)); 7448 __ cmp(ebx, Immediate(undefined_sentinel));
7401 __ j(equal, &no_info); 7449 __ j(equal, &no_info);
7402 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset)); 7450 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset));
7403
7404 // The type cell may have undefined in its value.
7405 __ cmp(edx, Immediate(undefined_sentinel));
7406 __ j(equal, &no_info);
7407
7408 // The type cell has either an AllocationSite or a JSFunction
7409 __ cmp(FieldOperand(edx, 0), Immediate(Handle<Map>( 7451 __ cmp(FieldOperand(edx, 0), Immediate(Handle<Map>(
7410 masm->isolate()->heap()->allocation_site_map()))); 7452 masm->isolate()->heap()->allocation_site_map())));
7411 __ j(not_equal, &no_info); 7453 __ j(not_equal, &no_info);
7412 7454
7413 __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset)); 7455 __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset));
7414 __ SmiUntag(edx); 7456 __ SmiUntag(edx);
7415 __ jmp(&switch_ready); 7457 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
7458
7416 __ bind(&no_info); 7459 __ bind(&no_info);
7417 __ mov(edx, Immediate(GetInitialFastElementsKind())); 7460 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
7418 __ bind(&switch_ready);
7419
7420 if (argument_count_ == ANY) {
7421 Label not_zero_case, not_one_case;
7422 __ test(eax, eax);
7423 __ j(not_zero, &not_zero_case);
7424 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
7425
7426 __ bind(&not_zero_case);
7427 __ cmp(eax, 1);
7428 __ j(greater, &not_one_case);
7429 CreateArrayDispatchOneArgument(masm);
7430
7431 __ bind(&not_one_case);
7432 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
7433 } else if (argument_count_ == NONE) {
7434 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
7435 } else if (argument_count_ == ONE) {
7436 CreateArrayDispatchOneArgument(masm);
7437 } else if (argument_count_ == MORE_THAN_ONE) {
7438 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
7439 } else {
7440 UNREACHABLE();
7441 }
7442 } 7461 }
7443 7462
7444 7463
7445 void InternalArrayConstructorStub::GenerateCase( 7464 void InternalArrayConstructorStub::GenerateCase(
7446 MacroAssembler* masm, ElementsKind kind) { 7465 MacroAssembler* masm, ElementsKind kind) {
7447 Label not_zero_case, not_one_case; 7466 Label not_zero_case, not_one_case;
7448 Label normal_sequence; 7467 Label normal_sequence;
7449 7468
7450 __ test(eax, eax); 7469 __ test(eax, eax);
7451 __ j(not_zero, &not_zero_case); 7470 __ j(not_zero, &not_zero_case);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
7528 __ bind(&fast_elements_case); 7547 __ bind(&fast_elements_case);
7529 GenerateCase(masm, FAST_ELEMENTS); 7548 GenerateCase(masm, FAST_ELEMENTS);
7530 } 7549 }
7531 7550
7532 7551
7533 #undef __ 7552 #undef __
7534 7553
7535 } } // namespace v8::internal 7554 } } // namespace v8::internal
7536 7555
7537 #endif // V8_TARGET_ARCH_IA32 7556 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698