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

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

Issue 22267005: Use StackArgumenstAccessor and kPCOnStackSize/kFPOnStackSize to compute stack address/operand (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased with master and refactored newly-introduced GenerateFastApiCall with StackArgumentsAccessor Created 7 years, 3 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 1961 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 __ bind(&miss); 1972 __ bind(&miss);
1973 1973
1974 StubCompiler::TailCallBuiltin( 1974 StubCompiler::TailCallBuiltin(
1975 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); 1975 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
1976 } 1976 }
1977 1977
1978 1978
1979 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { 1979 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
1980 // The key is in rdx and the parameter count is in rax. 1980 // The key is in rdx and the parameter count is in rax.
1981 1981
1982 // The displacement is used for skipping the frame pointer on the
1983 // stack. It is the offset of the last parameter (if any) relative
1984 // to the frame pointer.
1985 static const int kDisplacement = 1 * kPointerSize;
1986
1987 // Check that the key is a smi. 1982 // Check that the key is a smi.
1988 Label slow; 1983 Label slow;
1989 __ JumpIfNotSmi(rdx, &slow); 1984 __ JumpIfNotSmi(rdx, &slow);
1990 1985
1991 // Check if the calling frame is an arguments adaptor frame. We look at the 1986 // Check if the calling frame is an arguments adaptor frame. We look at the
1992 // context offset, and if the frame is not a regular one, then we find a 1987 // context offset, and if the frame is not a regular one, then we find a
1993 // Smi instead of the context. We can't use SmiCompare here, because that 1988 // Smi instead of the context. We can't use SmiCompare here, because that
1994 // only works for comparing two smis. 1989 // only works for comparing two smis.
1995 Label adaptor; 1990 Label adaptor;
1996 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 1991 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
1997 __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset), 1992 __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset),
1998 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 1993 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1999 __ j(equal, &adaptor); 1994 __ j(equal, &adaptor);
2000 1995
2001 // Check index against formal parameters count limit passed in 1996 // Check index against formal parameters count limit passed in
2002 // through register rax. Use unsigned comparison to get negative 1997 // through register rax. Use unsigned comparison to get negative
2003 // check for free. 1998 // check for free.
2004 __ cmpq(rdx, rax); 1999 __ cmpq(rdx, rax);
2005 __ j(above_equal, &slow); 2000 __ j(above_equal, &slow);
2006 2001
2007 // Read the argument from the stack and return it. 2002 // Read the argument from the stack and return it.
2008 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2); 2003 __ SmiSub(rax, rax, rdx);
2009 __ lea(rbx, Operand(rbp, index.reg, index.scale, 0)); 2004 __ SmiToInteger32(rax, rax);
2010 index = masm->SmiToNegativeIndex(rdx, rdx, kPointerSizeLog2); 2005 StackArgumentsAccessor args(rbp, rax, ARGUMENTS_DONT_CONTAIN_RECEIVER);
2011 __ movq(rax, Operand(rbx, index.reg, index.scale, kDisplacement)); 2006 __ movq(rax, args.GetArgumentOperand(0));
2012 __ Ret(); 2007 __ Ret();
2013 2008
2014 // Arguments adaptor case: Check index against actual arguments 2009 // Arguments adaptor case: Check index against actual arguments
2015 // limit found in the arguments adaptor frame. Use unsigned 2010 // limit found in the arguments adaptor frame. Use unsigned
2016 // comparison to get negative check for free. 2011 // comparison to get negative check for free.
2017 __ bind(&adaptor); 2012 __ bind(&adaptor);
2018 __ movq(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2013 __ movq(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
2019 __ cmpq(rdx, rcx); 2014 __ cmpq(rdx, rcx);
2020 __ j(above_equal, &slow); 2015 __ j(above_equal, &slow);
2021 2016
2022 // Read the argument from the stack and return it. 2017 // Read the argument from the stack and return it.
2023 index = masm->SmiToIndex(rax, rcx, kPointerSizeLog2); 2018 __ SmiSub(rcx, rcx, rdx);
2024 __ lea(rbx, Operand(rbx, index.reg, index.scale, 0)); 2019 __ SmiToInteger32(rcx, rcx);
2025 index = masm->SmiToNegativeIndex(rdx, rdx, kPointerSizeLog2); 2020 StackArgumentsAccessor adaptor_args(rbx, rcx,
2026 __ movq(rax, Operand(rbx, index.reg, index.scale, kDisplacement)); 2021 ARGUMENTS_DONT_CONTAIN_RECEIVER);
2022 __ movq(rax, adaptor_args.GetArgumentOperand(0));
2027 __ Ret(); 2023 __ Ret();
2028 2024
2029 // Slow-case: Handle non-smi or out-of-bounds access to arguments 2025 // Slow-case: Handle non-smi or out-of-bounds access to arguments
2030 // by calling the runtime system. 2026 // by calling the runtime system.
2031 __ bind(&slow); 2027 __ bind(&slow);
2032 __ PopReturnAddressTo(rbx); 2028 __ PopReturnAddressTo(rbx);
2033 __ push(rdx); 2029 __ push(rdx);
2034 __ PushReturnAddressFrom(rbx); 2030 __ PushReturnAddressFrom(rbx);
2035 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); 2031 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
2036 } 2032 }
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 2386 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
2391 #else // V8_INTERPRETED_REGEXP 2387 #else // V8_INTERPRETED_REGEXP
2392 2388
2393 // Stack frame on entry. 2389 // Stack frame on entry.
2394 // rsp[0] : return address 2390 // rsp[0] : return address
2395 // rsp[8] : last_match_info (expected JSArray) 2391 // rsp[8] : last_match_info (expected JSArray)
2396 // rsp[16] : previous index 2392 // rsp[16] : previous index
2397 // rsp[24] : subject string 2393 // rsp[24] : subject string
2398 // rsp[32] : JSRegExp object 2394 // rsp[32] : JSRegExp object
2399 2395
2400 static const int kLastMatchInfoOffset = 1 * kPointerSize; 2396 StackArgumentsAccessor args(rsp, 4, ARGUMENTS_DONT_CONTAIN_RECEIVER);
danno 2013/09/18 12:08:42 Since you are going through all the trouble to cle
haitao.feng 2013/09/22 08:16:00 Done.
2401 static const int kPreviousIndexOffset = 2 * kPointerSize; 2397 Operand StackOperandForJSRegExpObject = args.GetArgumentOperand(0);
danno 2013/09/18 12:08:42 nit: these variable names should start with a lowe
haitao.feng 2013/09/22 08:16:00 Removed these variables. On 2013/09/18 12:08:42, d
2402 static const int kSubjectOffset = 3 * kPointerSize; 2398 Operand StackOperandForSubjectString = args.GetArgumentOperand(1);
2403 static const int kJSRegExpOffset = 4 * kPointerSize; 2399 Operand StackOperandForPreviousIndex = args.GetArgumentOperand(2);
2400 Operand StackOperandForLastMatchInfo = args.GetArgumentOperand(3);
2404 2401
2405 Label runtime; 2402 Label runtime;
2406 // Ensure that a RegExp stack is allocated. 2403 // Ensure that a RegExp stack is allocated.
2407 Isolate* isolate = masm->isolate(); 2404 Isolate* isolate = masm->isolate();
2408 ExternalReference address_of_regexp_stack_memory_address = 2405 ExternalReference address_of_regexp_stack_memory_address =
2409 ExternalReference::address_of_regexp_stack_memory_address(isolate); 2406 ExternalReference::address_of_regexp_stack_memory_address(isolate);
2410 ExternalReference address_of_regexp_stack_memory_size = 2407 ExternalReference address_of_regexp_stack_memory_size =
2411 ExternalReference::address_of_regexp_stack_memory_size(isolate); 2408 ExternalReference::address_of_regexp_stack_memory_size(isolate);
2412 __ Load(kScratchRegister, address_of_regexp_stack_memory_size); 2409 __ Load(kScratchRegister, address_of_regexp_stack_memory_size);
2413 __ testq(kScratchRegister, kScratchRegister); 2410 __ testq(kScratchRegister, kScratchRegister);
2414 __ j(zero, &runtime); 2411 __ j(zero, &runtime);
2415 2412
2416 // Check that the first argument is a JSRegExp object. 2413 // Check that the first argument is a JSRegExp object.
2417 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2414 __ movq(rax, StackOperandForJSRegExpObject);
2418 __ JumpIfSmi(rax, &runtime); 2415 __ JumpIfSmi(rax, &runtime);
2419 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister); 2416 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
2420 __ j(not_equal, &runtime); 2417 __ j(not_equal, &runtime);
2421 2418
2422 // Check that the RegExp has been compiled (data contains a fixed array). 2419 // Check that the RegExp has been compiled (data contains a fixed array).
2423 __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset)); 2420 __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset));
2424 if (FLAG_debug_code) { 2421 if (FLAG_debug_code) {
2425 Condition is_smi = masm->CheckSmi(rax); 2422 Condition is_smi = masm->CheckSmi(rax);
2426 __ Check(NegateCondition(is_smi), 2423 __ Check(NegateCondition(is_smi),
2427 kUnexpectedTypeForRegExpDataFixedArrayExpected); 2424 kUnexpectedTypeForRegExpDataFixedArrayExpected);
(...skipping 12 matching lines...) Expand all
2440 __ SmiToInteger32(rdx, 2437 __ SmiToInteger32(rdx,
2441 FieldOperand(rax, JSRegExp::kIrregexpCaptureCountOffset)); 2438 FieldOperand(rax, JSRegExp::kIrregexpCaptureCountOffset));
2442 // Check (number_of_captures + 1) * 2 <= offsets vector size 2439 // Check (number_of_captures + 1) * 2 <= offsets vector size
2443 // Or number_of_captures <= offsets vector size / 2 - 1 2440 // Or number_of_captures <= offsets vector size / 2 - 1
2444 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); 2441 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
2445 __ cmpl(rdx, Immediate(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)); 2442 __ cmpl(rdx, Immediate(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1));
2446 __ j(above, &runtime); 2443 __ j(above, &runtime);
2447 2444
2448 // Reset offset for possibly sliced string. 2445 // Reset offset for possibly sliced string.
2449 __ Set(r14, 0); 2446 __ Set(r14, 0);
2450 __ movq(rdi, Operand(rsp, kSubjectOffset)); 2447 __ movq(rdi, StackOperandForSubjectString);
2451 __ JumpIfSmi(rdi, &runtime); 2448 __ JumpIfSmi(rdi, &runtime);
2452 __ movq(r15, rdi); // Make a copy of the original subject string. 2449 __ movq(r15, rdi); // Make a copy of the original subject string.
2453 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2450 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2454 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 2451 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
2455 // rax: RegExp data (FixedArray) 2452 // rax: RegExp data (FixedArray)
2456 // rdi: subject string 2453 // rdi: subject string
2457 // r15: subject string 2454 // r15: subject string
2458 // Handle subject string according to its encoding and representation: 2455 // Handle subject string according to its encoding and representation:
2459 // (1) Sequential two byte? If yes, go to (9). 2456 // (1) Sequential two byte? If yes, go to (9).
2460 // (2) Sequential one byte? If yes, go to (6). 2457 // (2) Sequential one byte? If yes, go to (6).
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2542 2539
2543 // rdi: sequential subject string (or look-alike, external string) 2540 // rdi: sequential subject string (or look-alike, external string)
2544 // r15: original subject string 2541 // r15: original subject string
2545 // rcx: encoding of subject string (1 if ASCII, 0 if two_byte); 2542 // rcx: encoding of subject string (1 if ASCII, 0 if two_byte);
2546 // r11: code 2543 // r11: code
2547 // Load used arguments before starting to push arguments for call to native 2544 // Load used arguments before starting to push arguments for call to native
2548 // RegExp code to avoid handling changing stack height. 2545 // RegExp code to avoid handling changing stack height.
2549 // We have to use r15 instead of rdi to load the length because rdi might 2546 // We have to use r15 instead of rdi to load the length because rdi might
2550 // have been only made to look like a sequential string when it actually 2547 // have been only made to look like a sequential string when it actually
2551 // is an external string. 2548 // is an external string.
2552 __ movq(rbx, Operand(rsp, kPreviousIndexOffset)); 2549 __ movq(rbx, StackOperandForPreviousIndex);
2553 __ JumpIfNotSmi(rbx, &runtime); 2550 __ JumpIfNotSmi(rbx, &runtime);
2554 __ SmiCompare(rbx, FieldOperand(r15, String::kLengthOffset)); 2551 __ SmiCompare(rbx, FieldOperand(r15, String::kLengthOffset));
2555 __ j(above_equal, &runtime); 2552 __ j(above_equal, &runtime);
2556 __ SmiToInteger64(rbx, rbx); 2553 __ SmiToInteger64(rbx, rbx);
2557 2554
2558 // rdi: subject string 2555 // rdi: subject string
2559 // rbx: previous index 2556 // rbx: previous index
2560 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); 2557 // rcx: encoding of subject string (1 if ASCII 0 if two_byte);
2561 // r11: code 2558 // r11: code
2562 // All checks done. Now push arguments for native regexp code. 2559 // All checks done. Now push arguments for native regexp code.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 // If none of the above, it can only be retry. 2663 // If none of the above, it can only be retry.
2667 // Handle that in the runtime system. 2664 // Handle that in the runtime system.
2668 __ j(not_equal, &runtime); 2665 __ j(not_equal, &runtime);
2669 2666
2670 // For failure return null. 2667 // For failure return null.
2671 __ LoadRoot(rax, Heap::kNullValueRootIndex); 2668 __ LoadRoot(rax, Heap::kNullValueRootIndex);
2672 __ ret(4 * kPointerSize); 2669 __ ret(4 * kPointerSize);
2673 2670
2674 // Load RegExp data. 2671 // Load RegExp data.
2675 __ bind(&success); 2672 __ bind(&success);
2676 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2673 __ movq(rax, StackOperandForJSRegExpObject);
2677 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset)); 2674 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
2678 __ SmiToInteger32(rax, 2675 __ SmiToInteger32(rax,
2679 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); 2676 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
2680 // Calculate number of capture registers (number_of_captures + 1) * 2. 2677 // Calculate number of capture registers (number_of_captures + 1) * 2.
2681 __ leal(rdx, Operand(rax, rax, times_1, 2)); 2678 __ leal(rdx, Operand(rax, rax, times_1, 2));
2682 2679
2683 // rdx: Number of capture registers 2680 // rdx: Number of capture registers
2684 // Check that the fourth object is a JSArray object. 2681 // Check that the fourth object is a JSArray object.
2685 __ movq(r15, Operand(rsp, kLastMatchInfoOffset)); 2682 __ movq(r15, StackOperandForLastMatchInfo);
2686 __ JumpIfSmi(r15, &runtime); 2683 __ JumpIfSmi(r15, &runtime);
2687 __ CmpObjectType(r15, JS_ARRAY_TYPE, kScratchRegister); 2684 __ CmpObjectType(r15, JS_ARRAY_TYPE, kScratchRegister);
2688 __ j(not_equal, &runtime); 2685 __ j(not_equal, &runtime);
2689 // Check that the JSArray is in fast case. 2686 // Check that the JSArray is in fast case.
2690 __ movq(rbx, FieldOperand(r15, JSArray::kElementsOffset)); 2687 __ movq(rbx, FieldOperand(r15, JSArray::kElementsOffset));
2691 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset)); 2688 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset));
2692 __ CompareRoot(rax, Heap::kFixedArrayMapRootIndex); 2689 __ CompareRoot(rax, Heap::kFixedArrayMapRootIndex);
2693 __ j(not_equal, &runtime); 2690 __ j(not_equal, &runtime);
2694 // Check that the last match info has space for the capture registers and the 2691 // Check that the last match info has space for the capture registers and the
2695 // additional information. Ensure no overflow in add. 2692 // additional information. Ensure no overflow in add.
2696 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); 2693 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
2697 __ SmiToInteger32(rax, FieldOperand(rbx, FixedArray::kLengthOffset)); 2694 __ SmiToInteger32(rax, FieldOperand(rbx, FixedArray::kLengthOffset));
2698 __ subl(rax, Immediate(RegExpImpl::kLastMatchOverhead)); 2695 __ subl(rax, Immediate(RegExpImpl::kLastMatchOverhead));
2699 __ cmpl(rdx, rax); 2696 __ cmpl(rdx, rax);
2700 __ j(greater, &runtime); 2697 __ j(greater, &runtime);
2701 2698
2702 // rbx: last_match_info backing store (FixedArray) 2699 // rbx: last_match_info backing store (FixedArray)
2703 // rdx: number of capture registers 2700 // rdx: number of capture registers
2704 // Store the capture count. 2701 // Store the capture count.
2705 __ Integer32ToSmi(kScratchRegister, rdx); 2702 __ Integer32ToSmi(kScratchRegister, rdx);
2706 __ movq(FieldOperand(rbx, RegExpImpl::kLastCaptureCountOffset), 2703 __ movq(FieldOperand(rbx, RegExpImpl::kLastCaptureCountOffset),
2707 kScratchRegister); 2704 kScratchRegister);
2708 // Store last subject and last input. 2705 // Store last subject and last input.
2709 __ movq(rax, Operand(rsp, kSubjectOffset)); 2706 __ movq(rax, StackOperandForSubjectString);
2710 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax); 2707 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax);
2711 __ movq(rcx, rax); 2708 __ movq(rcx, rax);
2712 __ RecordWriteField(rbx, 2709 __ RecordWriteField(rbx,
2713 RegExpImpl::kLastSubjectOffset, 2710 RegExpImpl::kLastSubjectOffset,
2714 rax, 2711 rax,
2715 rdi, 2712 rdi,
2716 kDontSaveFPRegs); 2713 kDontSaveFPRegs);
2717 __ movq(rax, rcx); 2714 __ movq(rax, rcx);
2718 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax); 2715 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax);
2719 __ RecordWriteField(rbx, 2716 __ RecordWriteField(rbx,
(...skipping 2224 matching lines...) Expand 10 before | Expand all | Expand 10 after
4944 4941
4945 void SubStringStub::Generate(MacroAssembler* masm) { 4942 void SubStringStub::Generate(MacroAssembler* masm) {
4946 Label runtime; 4943 Label runtime;
4947 4944
4948 // Stack frame on entry. 4945 // Stack frame on entry.
4949 // rsp[0] : return address 4946 // rsp[0] : return address
4950 // rsp[8] : to 4947 // rsp[8] : to
4951 // rsp[16] : from 4948 // rsp[16] : from
4952 // rsp[24] : string 4949 // rsp[24] : string
4953 4950
4954 const int kToOffset = 1 * kPointerSize; 4951 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
danno 2013/09/18 12:08:42 See comment above about using constants.
haitao.feng 2013/09/22 08:16:00 Done.
4955 const int kFromOffset = kToOffset + kPointerSize;
4956 const int kStringOffset = kFromOffset + kPointerSize;
4957 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
4958 4952
4959 // Make sure first argument is a string. 4953 // Make sure first argument is a string.
4960 __ movq(rax, Operand(rsp, kStringOffset)); 4954 __ movq(rax, args.GetArgumentOperand(0));
4961 STATIC_ASSERT(kSmiTag == 0); 4955 STATIC_ASSERT(kSmiTag == 0);
4962 __ testl(rax, Immediate(kSmiTagMask)); 4956 __ testl(rax, Immediate(kSmiTagMask));
4963 __ j(zero, &runtime); 4957 __ j(zero, &runtime);
4964 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx); 4958 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
4965 __ j(NegateCondition(is_string), &runtime); 4959 __ j(NegateCondition(is_string), &runtime);
4966 4960
4967 // rax: string 4961 // rax: string
4968 // rbx: instance type 4962 // rbx: instance type
4969 // Calculate length of sub string using the smi values. 4963 // Calculate length of sub string using the smi values.
4970 __ movq(rcx, Operand(rsp, kToOffset)); 4964 __ movq(rcx, args.GetArgumentOperand(2));
4971 __ movq(rdx, Operand(rsp, kFromOffset)); 4965 __ movq(rdx, args.GetArgumentOperand(1));
4972 __ JumpUnlessBothNonNegativeSmi(rcx, rdx, &runtime); 4966 __ JumpUnlessBothNonNegativeSmi(rcx, rdx, &runtime);
4973 4967
4974 __ SmiSub(rcx, rcx, rdx); // Overflow doesn't happen. 4968 __ SmiSub(rcx, rcx, rdx); // Overflow doesn't happen.
4975 __ cmpq(rcx, FieldOperand(rax, String::kLengthOffset)); 4969 __ cmpq(rcx, FieldOperand(rax, String::kLengthOffset));
4976 Label not_original_string; 4970 Label not_original_string;
4977 // Shorter than original string's length: an actual substring. 4971 // Shorter than original string's length: an actual substring.
4978 __ j(below, &not_original_string, Label::kNear); 4972 __ j(below, &not_original_string, Label::kNear);
4979 // Longer than original string's length or negative: unsafe arguments. 4973 // Longer than original string's length or negative: unsafe arguments.
4980 __ j(above, &runtime); 4974 __ j(above, &runtime);
4981 // Return original string. 4975 // Return original string.
4982 Counters* counters = masm->isolate()->counters(); 4976 Counters* counters = masm->isolate()->counters();
4983 __ IncrementCounter(counters->sub_string_native(), 1); 4977 __ IncrementCounter(counters->sub_string_native(), 1);
4984 __ ret(kArgumentsSize); 4978 __ ret(3 * kPointerSize);
danno 2013/09/18 12:08:42 You can use the argument count instead of a magic
haitao.feng 2013/09/22 08:16:00 Done.
4985 __ bind(&not_original_string); 4979 __ bind(&not_original_string);
4986 4980
4987 Label single_char; 4981 Label single_char;
4988 __ SmiCompare(rcx, Smi::FromInt(1)); 4982 __ SmiCompare(rcx, Smi::FromInt(1));
4989 __ j(equal, &single_char); 4983 __ j(equal, &single_char);
4990 4984
4991 __ SmiToInteger32(rcx, rcx); 4985 __ SmiToInteger32(rcx, rcx);
4992 4986
4993 // rax: string 4987 // rax: string
4994 // rbx: instance type 4988 // rbx: instance type
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5057 __ bind(&two_byte_slice); 5051 __ bind(&two_byte_slice);
5058 __ AllocateTwoByteSlicedString(rax, rbx, r14, &runtime); 5052 __ AllocateTwoByteSlicedString(rax, rbx, r14, &runtime);
5059 __ bind(&set_slice_header); 5053 __ bind(&set_slice_header);
5060 __ Integer32ToSmi(rcx, rcx); 5054 __ Integer32ToSmi(rcx, rcx);
5061 __ movq(FieldOperand(rax, SlicedString::kLengthOffset), rcx); 5055 __ movq(FieldOperand(rax, SlicedString::kLengthOffset), rcx);
5062 __ movq(FieldOperand(rax, SlicedString::kHashFieldOffset), 5056 __ movq(FieldOperand(rax, SlicedString::kHashFieldOffset),
5063 Immediate(String::kEmptyHashField)); 5057 Immediate(String::kEmptyHashField));
5064 __ movq(FieldOperand(rax, SlicedString::kParentOffset), rdi); 5058 __ movq(FieldOperand(rax, SlicedString::kParentOffset), rdi);
5065 __ movq(FieldOperand(rax, SlicedString::kOffsetOffset), rdx); 5059 __ movq(FieldOperand(rax, SlicedString::kOffsetOffset), rdx);
5066 __ IncrementCounter(counters->sub_string_native(), 1); 5060 __ IncrementCounter(counters->sub_string_native(), 1);
5067 __ ret(kArgumentsSize); 5061 __ ret(3 * kPointerSize);
5068 5062
5069 __ bind(&copy_routine); 5063 __ bind(&copy_routine);
5070 } 5064 }
5071 5065
5072 // rdi: underlying subject string 5066 // rdi: underlying subject string
5073 // rbx: instance type of underlying subject string 5067 // rbx: instance type of underlying subject string
5074 // rdx: adjusted start index (smi) 5068 // rdx: adjusted start index (smi)
5075 // rcx: length 5069 // rcx: length
5076 // The subject string can only be external or sequential string of either 5070 // The subject string can only be external or sequential string of either
5077 // encoding at this point. 5071 // encoding at this point.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5111 __ lea(rdi, FieldOperand(rax, SeqOneByteString::kHeaderSize)); 5105 __ lea(rdi, FieldOperand(rax, SeqOneByteString::kHeaderSize));
5112 5106
5113 // rax: result string 5107 // rax: result string
5114 // rcx: result length 5108 // rcx: result length
5115 // rdi: first character of result 5109 // rdi: first character of result
5116 // rsi: character of sub string start 5110 // rsi: character of sub string start
5117 // r14: original value of rsi 5111 // r14: original value of rsi
5118 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true); 5112 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
5119 __ movq(rsi, r14); // Restore rsi. 5113 __ movq(rsi, r14); // Restore rsi.
5120 __ IncrementCounter(counters->sub_string_native(), 1); 5114 __ IncrementCounter(counters->sub_string_native(), 1);
5121 __ ret(kArgumentsSize); 5115 __ ret(3 * kPointerSize);
5122 5116
5123 __ bind(&two_byte_sequential); 5117 __ bind(&two_byte_sequential);
5124 // Allocate the result. 5118 // Allocate the result.
5125 __ AllocateTwoByteString(rax, rcx, r11, r14, r15, &runtime); 5119 __ AllocateTwoByteString(rax, rcx, r11, r14, r15, &runtime);
5126 5120
5127 // rax: result string 5121 // rax: result string
5128 // rcx: result string length 5122 // rcx: result string length
5129 __ movq(r14, rsi); // esi used by following code. 5123 __ movq(r14, rsi); // esi used by following code.
5130 { // Locate character of sub string start. 5124 { // Locate character of sub string start.
5131 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_2); 5125 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_2);
5132 __ lea(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale, 5126 __ lea(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
5133 SeqOneByteString::kHeaderSize - kHeapObjectTag)); 5127 SeqOneByteString::kHeaderSize - kHeapObjectTag));
5134 } 5128 }
5135 // Locate first character of result. 5129 // Locate first character of result.
5136 __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize)); 5130 __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize));
5137 5131
5138 // rax: result string 5132 // rax: result string
5139 // rcx: result length 5133 // rcx: result length
5140 // rdi: first character of result 5134 // rdi: first character of result
5141 // rsi: character of sub string start 5135 // rsi: character of sub string start
5142 // r14: original value of rsi 5136 // r14: original value of rsi
5143 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false); 5137 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false);
5144 __ movq(rsi, r14); // Restore esi. 5138 __ movq(rsi, r14); // Restore esi.
5145 __ IncrementCounter(counters->sub_string_native(), 1); 5139 __ IncrementCounter(counters->sub_string_native(), 1);
5146 __ ret(kArgumentsSize); 5140 __ ret(3 * kPointerSize);
5147 5141
5148 // Just jump to runtime to create the sub string. 5142 // Just jump to runtime to create the sub string.
5149 __ bind(&runtime); 5143 __ bind(&runtime);
5150 __ TailCallRuntime(Runtime::kSubString, 3, 1); 5144 __ TailCallRuntime(Runtime::kSubString, 3, 1);
5151 5145
5152 __ bind(&single_char); 5146 __ bind(&single_char);
5153 // rax: string 5147 // rax: string
5154 // rbx: instance type 5148 // rbx: instance type
5155 // rcx: sub string length (smi) 5149 // rcx: sub string length (smi)
5156 // rdx: from index (smi) 5150 // rdx: from index (smi)
5157 StringCharAtGenerator generator( 5151 StringCharAtGenerator generator(
5158 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); 5152 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
5159 generator.GenerateFast(masm); 5153 generator.GenerateFast(masm);
5160 __ ret(kArgumentsSize); 5154 __ ret(3 * kPointerSize);
5161 generator.SkipSlow(masm, &runtime); 5155 generator.SkipSlow(masm, &runtime);
5162 } 5156 }
5163 5157
5164 5158
5165 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, 5159 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm,
5166 Register left, 5160 Register left,
5167 Register right, 5161 Register right,
5168 Register scratch1, 5162 Register scratch1,
5169 Register scratch2) { 5163 Register scratch2) {
5170 Register length = scratch1; 5164 Register length = scratch1;
(...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after
6623 __ bind(&fast_elements_case); 6617 __ bind(&fast_elements_case);
6624 GenerateCase(masm, FAST_ELEMENTS); 6618 GenerateCase(masm, FAST_ELEMENTS);
6625 } 6619 }
6626 6620
6627 6621
6628 #undef __ 6622 #undef __
6629 6623
6630 } } // namespace v8::internal 6624 } } // namespace v8::internal
6631 6625
6632 #endif // V8_TARGET_ARCH_X64 6626 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-x64.h » ('j') | src/x64/macro-assembler-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698