OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 3749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3760 __ SmiToInteger32(index.reg(), index.reg()); | 3760 __ SmiToInteger32(index.reg(), index.reg()); |
3761 | 3761 |
3762 __ bind(&try_again_with_new_string); | 3762 __ bind(&try_again_with_new_string); |
3763 // Fetch the instance type of the receiver into rcx. | 3763 // Fetch the instance type of the receiver into rcx. |
3764 __ movq(rcx, FieldOperand(object.reg(), HeapObject::kMapOffset)); | 3764 __ movq(rcx, FieldOperand(object.reg(), HeapObject::kMapOffset)); |
3765 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); | 3765 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); |
3766 // If the receiver is not a string trigger the slow case. | 3766 // If the receiver is not a string trigger the slow case. |
3767 __ testb(rcx, Immediate(kIsNotStringMask)); | 3767 __ testb(rcx, Immediate(kIsNotStringMask)); |
3768 __ j(not_zero, &slow_case); | 3768 __ j(not_zero, &slow_case); |
3769 | 3769 |
3770 // Here we make assumptions about the tag values and the shifts needed. | |
3771 // See the comment in objects.h. | |
3772 ASSERT(kLongStringTag == 0); | |
3773 ASSERT(kMediumStringTag + String::kLongLengthShift == | |
3774 String::kMediumLengthShift); | |
3775 ASSERT(kShortStringTag + String::kLongLengthShift == | |
3776 String::kShortLengthShift); | |
3777 __ and_(rcx, Immediate(kStringSizeMask)); | |
3778 __ addq(rcx, Immediate(String::kLongLengthShift)); | |
3779 // Fetch the length field into the temporary register. | |
3780 __ movl(temp.reg(), FieldOperand(object.reg(), String::kLengthOffset)); | |
3781 __ shrl_cl(temp.reg()); | |
3782 // Check for index out of range. | 3770 // Check for index out of range. |
3783 __ cmpl(index.reg(), temp.reg()); | 3771 __ cmpl(index.reg(), FieldOperand(object.reg(), String::kLengthOffset)); |
3784 __ j(greater_equal, &slow_case); | 3772 __ j(greater_equal, &slow_case); |
3785 // Reload the instance type (into the temp register this time).. | 3773 // Reload the instance type (into the temp register this time).. |
3786 __ movq(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset)); | 3774 __ movq(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset)); |
3787 __ movzxbl(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset)); | 3775 __ movzxbl(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset)); |
3788 | 3776 |
3789 // We need special handling for non-flat strings. | 3777 // We need special handling for non-flat strings. |
3790 ASSERT_EQ(0, kSeqStringTag); | 3778 ASSERT_EQ(0, kSeqStringTag); |
3791 __ testb(temp.reg(), Immediate(kStringRepresentationMask)); | 3779 __ testb(temp.reg(), Immediate(kStringRepresentationMask)); |
3792 __ j(not_zero, ¬_a_flat_string); | 3780 __ j(not_zero, ¬_a_flat_string); |
3793 // Check for 1-byte or 2-byte string. | 3781 // Check for 1-byte or 2-byte string. |
(...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6168 __ and_(rbx, Immediate(1 << Map::kIsUndetectable)); | 6156 __ and_(rbx, Immediate(1 << Map::kIsUndetectable)); |
6169 __ j(not_zero, &false_result); | 6157 __ j(not_zero, &false_result); |
6170 | 6158 |
6171 // JavaScript object => true. | 6159 // JavaScript object => true. |
6172 __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE)); | 6160 __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE)); |
6173 __ j(above_equal, &true_result); | 6161 __ j(above_equal, &true_result); |
6174 | 6162 |
6175 // String value => false iff empty. | 6163 // String value => false iff empty. |
6176 __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE)); | 6164 __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE)); |
6177 __ j(above_equal, ¬_string); | 6165 __ j(above_equal, ¬_string); |
6178 __ and_(rcx, Immediate(kStringSizeMask)); | |
6179 __ cmpq(rcx, Immediate(kShortStringTag)); | |
6180 __ j(not_equal, &true_result); // Empty string is always short. | |
6181 __ movl(rdx, FieldOperand(rax, String::kLengthOffset)); | 6166 __ movl(rdx, FieldOperand(rax, String::kLengthOffset)); |
6182 __ shr(rdx, Immediate(String::kShortLengthShift)); | 6167 __ testl(rdx, rdx); |
6183 __ j(zero, &false_result); | 6168 __ j(zero, &false_result); |
6184 __ jmp(&true_result); | 6169 __ jmp(&true_result); |
6185 | 6170 |
6186 __ bind(¬_string); | 6171 __ bind(¬_string); |
6187 // HeapNumber => false iff +0, -0, or NaN. | 6172 // HeapNumber => false iff +0, -0, or NaN. |
6188 // These three cases set C3 when compared to zero in the FPU. | 6173 // These three cases set C3 when compared to zero in the FPU. |
6189 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); | 6174 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); |
6190 __ j(not_equal, &true_result); | 6175 __ j(not_equal, &true_result); |
6191 __ fldz(); // Load zero onto fp stack | 6176 __ fldz(); // Load zero onto fp stack |
6192 // Load heap-number double value onto fp stack | 6177 // Load heap-number double value onto fp stack |
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7886 masm.GetCode(&desc); | 7871 masm.GetCode(&desc); |
7887 // Call the function from C++. | 7872 // Call the function from C++. |
7888 return FUNCTION_CAST<ModuloFunction>(buffer); | 7873 return FUNCTION_CAST<ModuloFunction>(buffer); |
7889 } | 7874 } |
7890 | 7875 |
7891 #endif | 7876 #endif |
7892 | 7877 |
7893 #undef __ | 7878 #undef __ |
7894 | 7879 |
7895 } } // namespace v8::internal | 7880 } } // namespace v8::internal |
OLD | NEW |