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

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

Issue 548179: Port direct call from JavaScript to native RegExp to x64... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "codegen-inl.h" 31 #include "codegen-inl.h"
32 #include "compiler.h" 32 #include "compiler.h"
33 #include "debug.h" 33 #include "debug.h"
34 #include "ic-inl.h" 34 #include "ic-inl.h"
35 #include "parser.h" 35 #include "parser.h"
36 #include "regexp-macro-assembler.h"
36 #include "register-allocator-inl.h" 37 #include "register-allocator-inl.h"
37 #include "scopes.h" 38 #include "scopes.h"
38 39
39 namespace v8 { 40 namespace v8 {
40 namespace internal { 41 namespace internal {
41 42
42 #define __ ACCESS_MASM(masm_) 43 #define __ ACCESS_MASM(masm_)
43 44
44 // ------------------------------------------------------------------------- 45 // -------------------------------------------------------------------------
45 // Platform-specific DeferredCode functions. 46 // Platform-specific DeferredCode functions.
(...skipping 3902 matching lines...) Expand 10 before | Expand all | Expand 10 after
3948 3949
3949 3950
3950 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { 3951 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
3951 ASSERT_EQ(args->length(), 4); 3952 ASSERT_EQ(args->length(), 4);
3952 3953
3953 // Load the arguments on the stack and call the runtime system. 3954 // Load the arguments on the stack and call the runtime system.
3954 Load(args->at(0)); 3955 Load(args->at(0));
3955 Load(args->at(1)); 3956 Load(args->at(1));
3956 Load(args->at(2)); 3957 Load(args->at(2));
3957 Load(args->at(3)); 3958 Load(args->at(3));
3958 Result result = frame_->CallRuntime(Runtime::kRegExpExec, 4); 3959 RegExpExecStub stub;
3960 Result result = frame_->CallStub(&stub, 4);
3959 frame_->Push(&result); 3961 frame_->Push(&result);
3960 } 3962 }
3961 3963
3962 3964
3963 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) { 3965 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
3964 ASSERT_EQ(2, args->length()); 3966 ASSERT_EQ(2, args->length());
3965 3967
3966 Load(args->at(0)); 3968 Load(args->at(0));
3967 Load(args->at(1)); 3969 Load(args->at(1));
3968 3970
(...skipping 2587 matching lines...) Expand 10 before | Expand all | Expand 10 after
6556 break; 6558 break;
6557 case Token::BIT_NOT: 6559 case Token::BIT_NOT:
6558 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION); 6560 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION);
6559 break; 6561 break;
6560 default: 6562 default:
6561 UNREACHABLE(); 6563 UNREACHABLE();
6562 } 6564 }
6563 } 6565 }
6564 6566
6565 6567
6568 void RegExpExecStub::Generate(MacroAssembler* masm) {
6569 // Just jump directly to runtime if native RegExp is not selected at compile
6570 // time or if regexp entry in generated code is turned off runtime switch or
6571 // at compilation.
6572 #ifndef V8_NATIVE_REGEXP
6573 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
6574 #endif
6575 if (!FLAG_regexp_entry_native) {
6576 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
6577 return;
6578 }
6579
6580 // Stack frame on entry.
6581 // esp[0]: return address
6582 // esp[8]: last_match_info (expected JSArray)
6583 // esp[16]: previous index
6584 // esp[24]: subject string
6585 // esp[32]: JSRegExp object
6586
6587 static const int kLastMatchInfoOffset = 1 * kPointerSize;
6588 static const int kPreviousIndexOffset = 2 * kPointerSize;
6589 static const int kSubjectOffset = 3 * kPointerSize;
6590 static const int kJSRegExpOffset = 4 * kPointerSize;
6591
6592 Label runtime;
6593
6594 // Ensure that a RegExp stack is allocated.
6595 ExternalReference address_of_regexp_stack_memory_address =
6596 ExternalReference::address_of_regexp_stack_memory_address();
6597 ExternalReference address_of_regexp_stack_memory_size =
6598 ExternalReference::address_of_regexp_stack_memory_size();
6599 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
6600 __ movq(kScratchRegister, Operand(kScratchRegister, 0));
6601 __ testq(kScratchRegister, kScratchRegister);
6602 __ j(zero, &runtime);
6603
6604
6605 // Check that the first argument is a JSRegExp object.
6606 __ movq(rax, Operand(rsp, kJSRegExpOffset));
6607 __ JumpIfSmi(rax, &runtime);
6608 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
6609 __ j(not_equal, &runtime);
6610 // Check that the RegExp has been compiled (data contains a fixed array).
6611 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
6612 if (FLAG_debug_code) {
6613 Condition is_smi = masm->CheckSmi(rcx);
6614 __ Check(NegateCondition(is_smi),
6615 "Unexpected type for RegExp data, FixedArray expected");
6616 __ CmpObjectType(rcx, FIXED_ARRAY_TYPE, kScratchRegister);
6617 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
6618 }
6619
6620 // rcx: RegExp data (FixedArray)
6621 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
6622 __ movq(rbx, FieldOperand(rcx, JSRegExp::kDataTagOffset));
6623 __ SmiCompare(rbx, Smi::FromInt(JSRegExp::IRREGEXP));
6624 __ j(not_equal, &runtime);
6625
6626 // rcx: RegExp data (FixedArray)
6627 // Check that the number of captures fit in the static offsets vector buffer.
6628 __ movq(rdx, FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
6629 // Calculate number of capture registers (number_of_captures + 1) * 2.
6630 __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rdx, 1);
6631 __ addq(rdx, Immediate(2)); // rdx was number_of_captures * 2.
6632 // Check that the static offsets vector buffer is large enough.
6633 __ cmpq(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize));
6634 __ j(above, &runtime);
6635
6636 // rcx: RegExp data (FixedArray)
6637 // rdx: Number of capture registers
6638 // Check that the second argument is a string.
6639 __ movq(rax, Operand(rsp, kSubjectOffset));
6640 __ JumpIfSmi(rax, &runtime);
6641 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
6642 __ j(NegateCondition(is_string), &runtime);
6643 // Get the length of the string to rbx.
6644 __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
6645
6646 // rbx: Length of subject string
6647 // rcx: RegExp data (FixedArray)
6648 // rdx: Number of capture registers
6649 // Check that the third argument is a positive smi less than the string
6650 // length. A negative value will be greater (usigned comparison).
6651 __ movq(rax, Operand(rsp, kPreviousIndexOffset));
6652 __ SmiToInteger32(rax, rax);
6653 __ cmpl(rax, rbx);
6654 __ j(greater, &runtime);
Lasse Reichstein 2010/01/29 08:09:08 greater -> above
Søren Thygesen Gjesse 2010/01/29 13:06:53 Thanks, fixed in ia32 version as well.
6655
6656 // rcx: RegExp data (FixedArray)
6657 // rdx: Number of capture registers
6658 // Check that the fourth object is a JSArray object.
6659 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
6660 __ JumpIfSmi(rax, &runtime);
6661 __ CmpObjectType(rax, JS_ARRAY_TYPE, kScratchRegister);
6662 __ j(not_equal, &runtime);
6663 // Check that the JSArray is in fast case.
6664 __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset));
6665 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset));
6666 __ Cmp(rax, Factory::fixed_array_map());
6667 __ j(not_equal, &runtime);
6668 // Check that the last match info has space for the capture registers and the
6669 // additional information. Ensure no overflow in add.
6670 ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
6671 __ movl(rax, FieldOperand(rbx, FixedArray::kLengthOffset));
6672 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
6673 __ cmpl(rdx, rax);
6674 __ j(greater, &runtime);
6675
6676 // ecx: RegExp data (FixedArray)
6677 // Check the representation and encoding of the subject string.
6678 Label seq_string, seq_two_byte_string, check_code;
6679 const int kStringRepresentationEncodingMask =
6680 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
6681 __ movq(rax, Operand(rsp, kSubjectOffset));
6682 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
6683 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
6684 __ andb(rbx, Immediate(kStringRepresentationEncodingMask));
6685 // First check for sequential string.
6686 ASSERT_EQ(0, kStringTag);
6687 ASSERT_EQ(0, kSeqStringTag);
6688 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
6689 __ j(zero, &seq_string);
6690
6691 // Check for flat cons string.
6692 // A flat cons string is a cons string where the second part is the empty
6693 // string. In that case the subject string is just the first part of the cons
6694 // string. Also in this case the first part of the cons string is known to be
6695 // a sequential string or an external string.
6696 __ movl(rdx, rbx);
6697 __ andb(rdx, Immediate(kStringRepresentationMask));
6698 __ cmpb(rdx, Immediate(kConsStringTag));
6699 __ j(not_equal, &runtime);
6700 __ movq(rdx, FieldOperand(rax, ConsString::kSecondOffset));
6701 __ Cmp(rdx, Factory::empty_string());
6702 __ j(not_equal, &runtime);
6703 __ movq(rax, FieldOperand(rax, ConsString::kFirstOffset));
6704 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
6705 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
6706 ASSERT_EQ(0, kSequentialStringTag);
6707 __ testb(rbx, Immediate(kStringRepresentationMask));
6708 __ j(not_zero, &runtime);
6709 __ andb(rbx, Immediate(kStringRepresentationEncodingMask));
Lasse Reichstein 2010/01/29 08:09:08 Do you need the representation bits any more? You
Søren Thygesen Gjesse 2010/01/29 13:06:53 The reason is that the jump to label seq_string fr
6710
6711 __ bind(&seq_string);
6712 // rax: subject string (sequential either ascii to two byte)
6713 // rbx: suject string type & kStringRepresentationEncodingMask
6714 // rcx: RegExp data (FixedArray)
6715 // Check that the irregexp code has been generated for an ascii string. If
6716 // it has, the field contains a code object otherwise it contains the hole.
6717 __ cmpb(rbx, Immediate(kStringTag | kSeqStringTag | kTwoByteStringTag));
6718 __ j(equal, &seq_two_byte_string);
6719 if (FLAG_debug_code) {
6720 __ cmpb(rbx, Immediate(kStringTag | kSeqStringTag | kAsciiStringTag));
6721 __ Check(equal, "Expected sequential ascii string");
6722 }
6723 __ movq(r12, FieldOperand(rcx, JSRegExp::kDataAsciiCodeOffset));
6724 __ Set(rdi, 1); // Type is ascii.
6725 __ jmp(&check_code);
6726
6727 __ bind(&seq_two_byte_string);
6728 // rax: subject string
6729 // rcx: RegExp data (FixedArray)
6730 __ movq(r12, FieldOperand(rcx, JSRegExp::kDataUC16CodeOffset));
6731 __ Set(rdi, 0); // Type is two byte.
6732
6733 __ bind(&check_code);
6734 // Check that the irregexp code has been generated for the actual string
6735 // encoding. If it has, the field contains a code object otherwise it contains
6736 // the hole.
6737 __ CmpObjectType(r12, CODE_TYPE, kScratchRegister);
6738 __ j(not_equal, &runtime);
6739
6740 // rax: subject string
6741 // rdi: encoding of subject string (1 if ascii, 0 if two_byte);
6742 // r12: code
6743 // Load used arguments before starting to push arguments for call to native
6744 // RegExp code to avoid handling changing stack height.
6745 __ movq(rbx, Operand(rsp, kPreviousIndexOffset));
6746 __ SmiToInteger64(rbx, rbx); // Previous index from smi.
6747
6748 // rax: subject string
6749 // rbx: previous index
6750 // rdi: encoding of subject string (1 if ascii 0 if two_byte);
6751 // r12: code
6752 // All checks done. Now push arguments for native regexp code.
6753 __ IncrementCounter(&Counters::regexp_entry_native, 1);
6754
6755 // rsi is caller save on Windows and used to pass parameter on Linux.
6756 __ push(rsi);
6757
6758 static const int kRegExpExecuteArguments = 7;
6759 __ PrepareCallCFunction(kRegExpExecuteArguments);
6760 int argument_slots_on_stack =
6761 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
6762
6763 // Argument 7: Indicate that this is a direct call from JavaScript.
6764 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
6765 Immediate(1));
6766
6767 // Argument 6: Start (high end) of backtracking stack memory area.
6768 __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
6769 __ movq(r9, Operand(kScratchRegister, 0));
6770 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
6771 __ addq(r9, Operand(kScratchRegister, 0));
6772 // Argument 6 passed in r9 on Linux and on the stack on Windows.
6773 #ifdef _WIN64
6774 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), r9);
6775 #endif
6776
6777 // Argument 5: static offsets vector buffer.
6778 __ movq(r8, ExternalReference::address_of_static_offsets_vector());
6779 // Argument 5 passed in r8 on Linux and on the stack on Windows.
6780 #ifdef _WIN64
6781 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r8);
6782 #endif
6783
6784 // First four arguments are passed in registers on both Linux and Windows.
6785 #ifdef _WIN64
6786 Register arg4 = r9;
6787 Register arg3 = r8;
6788 Register arg2 = rdx;
6789 Register arg1 = rcx;
6790 #else
6791 Register arg4 = rcx;
6792 Register arg3 = rdx;
6793 Register arg2 = rsi;
6794 Register arg1 = rdi;
6795 #endif
6796
6797 // Keep track on aliasing between argX defined above and the registers used.
6798 // rax: subject string
6799 // rbx: previous index
6800 // rdi: encoding of subject string (1 if ascii 0 if two_byte);
6801 // r12: code
6802
6803 // Argument 4: End of string data
6804 // Argument 3: Start of string data
6805 Label setup_two_byte, setup_rest;
6806 __ testb(rdi, rdi);
6807 __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
6808 __ j(zero, &setup_two_byte);
6809 __ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize));
6810 __ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize));
6811 __ jmp(&setup_rest);
6812 __ bind(&setup_two_byte);
6813 __ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize));
6814 __ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize));
6815
6816 __ bind(&setup_rest);
6817 // Argument 2: Previous index.
6818 __ movq(arg2, rbx);
6819
6820 // Argument 1: Subject string.
6821 __ movq(arg1, rax);
6822
6823 // Locate the code entry and call it.
6824 __ addq(r12, Immediate(Code::kHeaderSize - kHeapObjectTag));
6825 __ CallCFunction(r12, kRegExpExecuteArguments);
6826
6827 // rsi is caller save, as it is used to pass parameter.
6828 __ pop(rsi);
6829
6830 // Check the result.
6831 Label success;
6832 __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS));
6833 __ j(equal, &success);
6834 Label failure;
6835 __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::FAILURE));
6836 __ j(equal, &failure);
6837 __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION));
6838 // If not exception it can only be retry. Handle that in the runtime system.
6839 __ j(not_equal, &runtime);
6840 // Result must now be exception. If there is no pending exception already a
6841 // stack overflow (on the backtrack stack) was detected in RegExp code but
6842 // haven't created the exception yet. Handle that in the runtime system.
6843 // TODO(592) Rerunning the RegExp to get the stack overflow exception.
6844 ExternalReference pending_exception_address(Top::k_pending_exception_address);
6845 __ movq(kScratchRegister, pending_exception_address);
6846 __ Cmp(kScratchRegister, Factory::the_hole_value());
6847 __ j(equal, &runtime);
6848 __ bind(&failure);
6849 // For failure and exception return null.
6850 __ Move(rax, Factory::null_value());
6851 __ ret(4 * kPointerSize);
6852
6853 // Load RegExp data.
6854 __ bind(&success);
6855 __ movq(rax, Operand(rsp, kJSRegExpOffset));
6856 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
6857 __ movq(rdx, FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
6858 // Calculate number of capture registers (number_of_captures + 1) * 2.
6859 __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rdx, 1);
6860 __ addq(rdx, Immediate(2)); // rdx was number_of_captures * 2.
6861
6862 // rdx: Number of capture registers
6863 // Load last_match_info which is still known to be a fast case JSArray.
6864 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
6865 __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset));
6866
6867 // rbx: last_match_info backing store (FixedArray)
6868 // rdx: number of capture registers
6869 // Store the capture count.
6870 __ Integer32ToSmi(kScratchRegister, rdx);
6871 __ movq(FieldOperand(rbx, RegExpImpl::kLastCaptureCountOffset),
6872 kScratchRegister);
6873 // Store last subject and last input.
6874 __ movq(rax, Operand(rsp, kSubjectOffset));
6875 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax);
6876 __ movq(rcx, rbx);
6877 __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi);
6878 __ movq(rax, Operand(rsp, kSubjectOffset));
6879 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax);
6880 __ movq(rcx, rbx);
6881 __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi);
6882
6883 // Get the static offsets vector filled by the native regexp code.
6884 __ movq(rcx, ExternalReference::address_of_static_offsets_vector());
6885
6886 // rbx: last_match_info backing store (FixedArray)
6887 // rcx: offsets vector
6888 // rdx: number of capture registers
6889 Label next_capture, done;
6890 __ movq(rax, Operand(rsp, kPreviousIndexOffset));
6891 // Capture register counter starts from number of capture registers and
6892 // counts down until wraping after zero.
6893 __ bind(&next_capture);
6894 __ subq(rdx, Immediate(1));
6895 __ j(negative, &done);
6896 // Read the value from the static offsets vector buffer and make it a smi.
6897 __ movl(rdi, Operand(rcx, rdx, times_int_size, 0));
6898 __ Integer32ToSmi(rdi, rdi, &runtime);
6899 // Add previous index (from its stack slot) if value is not negative.
6900 Label capture_negative;
6901 // Negative flag set by smi convertion above.
6902 __ j(negative, &capture_negative);
6903 __ SmiAdd(rdi, rdi, rax, &runtime); // Add previous index.
6904 __ bind(&capture_negative);
6905 // Store the smi value in the last match info.
6906 __ movq(FieldOperand(rbx,
6907 rdx,
6908 times_pointer_size,
6909 RegExpImpl::kFirstCaptureOffset),
6910 rdi);
6911 __ jmp(&next_capture);
6912 __ bind(&done);
6913
6914 // Return last match info.
6915 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
6916 __ ret(4 * kPointerSize);
6917
6918 // Do the runtime call to execute the regexp.
6919 __ bind(&runtime);
6920 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
6921 }
6922
6923
6566 void CompareStub::Generate(MacroAssembler* masm) { 6924 void CompareStub::Generate(MacroAssembler* masm) {
6567 Label call_builtin, done; 6925 Label call_builtin, done;
6568 6926
6569 // NOTICE! This code is only reached after a smi-fast-case check, so 6927 // NOTICE! This code is only reached after a smi-fast-case check, so
6570 // it is certain that at least one operand isn't a smi. 6928 // it is certain that at least one operand isn't a smi.
6571 6929
6572 if (cc_ == equal) { // Both strict and non-strict. 6930 if (cc_ == equal) { // Both strict and non-strict.
6573 Label slow; // Fallthrough label. 6931 Label slow; // Fallthrough label.
6574 // Equality is almost reflexive (everything but NaN), so start by testing 6932 // Equality is almost reflexive (everything but NaN), so start by testing
6575 // for "identity and not NaN". 6933 // for "identity and not NaN".
(...skipping 2180 matching lines...) Expand 10 before | Expand all | Expand 10 after
8756 // Call the function from C++. 9114 // Call the function from C++.
8757 return FUNCTION_CAST<ModuloFunction>(buffer); 9115 return FUNCTION_CAST<ModuloFunction>(buffer);
8758 } 9116 }
8759 9117
8760 #endif 9118 #endif
8761 9119
8762 9120
8763 #undef __ 9121 #undef __
8764 9122
8765 } } // namespace v8::internal 9123 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698