| OLD | NEW |
| 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 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 __ ldr(r3, FieldMemOperand(rhs, HeapObject::kMapOffset)); | 965 __ ldr(r3, FieldMemOperand(rhs, HeapObject::kMapOffset)); |
| 966 __ ldrb(r2, FieldMemOperand(r2, Map::kBitFieldOffset)); | 966 __ ldrb(r2, FieldMemOperand(r2, Map::kBitFieldOffset)); |
| 967 __ ldrb(r3, FieldMemOperand(r3, Map::kBitFieldOffset)); | 967 __ ldrb(r3, FieldMemOperand(r3, Map::kBitFieldOffset)); |
| 968 __ and_(r0, r2, Operand(r3)); | 968 __ and_(r0, r2, Operand(r3)); |
| 969 __ and_(r0, r0, Operand(1 << Map::kIsUndetectable)); | 969 __ and_(r0, r0, Operand(1 << Map::kIsUndetectable)); |
| 970 __ eor(r0, r0, Operand(1 << Map::kIsUndetectable)); | 970 __ eor(r0, r0, Operand(1 << Map::kIsUndetectable)); |
| 971 __ Ret(); | 971 __ Ret(); |
| 972 } | 972 } |
| 973 | 973 |
| 974 | 974 |
| 975 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | |
| 976 Register object, | |
| 977 Register result, | |
| 978 Register scratch1, | |
| 979 Register scratch2, | |
| 980 Register scratch3, | |
| 981 Label* not_found) { | |
| 982 // Use of registers. Register result is used as a temporary. | |
| 983 Register number_string_cache = result; | |
| 984 Register mask = scratch3; | |
| 985 | |
| 986 // Load the number string cache. | |
| 987 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
| 988 | |
| 989 // Make the hash mask from the length of the number string cache. It | |
| 990 // contains two elements (number and string) for each cache entry. | |
| 991 __ ldr(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); | |
| 992 // Divide length by two (length is a smi). | |
| 993 __ mov(mask, Operand(mask, ASR, kSmiTagSize + 1)); | |
| 994 __ sub(mask, mask, Operand(1)); // Make mask. | |
| 995 | |
| 996 // Calculate the entry in the number string cache. The hash value in the | |
| 997 // number string cache for smis is just the smi value, and the hash for | |
| 998 // doubles is the xor of the upper and lower words. See | |
| 999 // Heap::GetNumberStringCache. | |
| 1000 Isolate* isolate = masm->isolate(); | |
| 1001 Label is_smi; | |
| 1002 Label load_result_from_cache; | |
| 1003 __ JumpIfSmi(object, &is_smi); | |
| 1004 __ CheckMap(object, | |
| 1005 scratch1, | |
| 1006 Heap::kHeapNumberMapRootIndex, | |
| 1007 not_found, | |
| 1008 DONT_DO_SMI_CHECK); | |
| 1009 | |
| 1010 STATIC_ASSERT(8 == kDoubleSize); | |
| 1011 __ add(scratch1, | |
| 1012 object, | |
| 1013 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); | |
| 1014 __ ldm(ia, scratch1, scratch1.bit() | scratch2.bit()); | |
| 1015 __ eor(scratch1, scratch1, Operand(scratch2)); | |
| 1016 __ and_(scratch1, scratch1, Operand(mask)); | |
| 1017 | |
| 1018 // Calculate address of entry in string cache: each entry consists | |
| 1019 // of two pointer sized fields. | |
| 1020 __ add(scratch1, | |
| 1021 number_string_cache, | |
| 1022 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); | |
| 1023 | |
| 1024 Register probe = mask; | |
| 1025 __ ldr(probe, | |
| 1026 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); | |
| 1027 __ JumpIfSmi(probe, not_found); | |
| 1028 __ sub(scratch2, object, Operand(kHeapObjectTag)); | |
| 1029 __ vldr(d0, scratch2, HeapNumber::kValueOffset); | |
| 1030 __ sub(probe, probe, Operand(kHeapObjectTag)); | |
| 1031 __ vldr(d1, probe, HeapNumber::kValueOffset); | |
| 1032 __ VFPCompareAndSetFlags(d0, d1); | |
| 1033 __ b(ne, not_found); // The cache did not contain this value. | |
| 1034 __ b(&load_result_from_cache); | |
| 1035 | |
| 1036 __ bind(&is_smi); | |
| 1037 Register scratch = scratch1; | |
| 1038 __ and_(scratch, mask, Operand(object, ASR, 1)); | |
| 1039 // Calculate address of entry in string cache: each entry consists | |
| 1040 // of two pointer sized fields. | |
| 1041 __ add(scratch, | |
| 1042 number_string_cache, | |
| 1043 Operand(scratch, LSL, kPointerSizeLog2 + 1)); | |
| 1044 | |
| 1045 // Check if the entry is the smi we are looking for. | |
| 1046 __ ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | |
| 1047 __ cmp(object, probe); | |
| 1048 __ b(ne, not_found); | |
| 1049 | |
| 1050 // Get the result from the cache. | |
| 1051 __ bind(&load_result_from_cache); | |
| 1052 __ ldr(result, | |
| 1053 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); | |
| 1054 __ IncrementCounter(isolate->counters()->number_to_string_native(), | |
| 1055 1, | |
| 1056 scratch1, | |
| 1057 scratch2); | |
| 1058 } | |
| 1059 | |
| 1060 | |
| 1061 void NumberToStringStub::Generate(MacroAssembler* masm) { | 975 void NumberToStringStub::Generate(MacroAssembler* masm) { |
| 1062 Label runtime; | 976 Label runtime; |
| 1063 | 977 |
| 1064 __ ldr(r1, MemOperand(sp, 0)); | 978 __ ldr(r1, MemOperand(sp, 0)); |
| 1065 | 979 |
| 1066 // Generate code to lookup number in the number string cache. | 980 // Generate code to lookup number in the number string cache. |
| 1067 GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, r4, &runtime); | 981 __ LookupNumberStringCache(r1, r0, r2, r3, r4, &runtime); |
| 1068 __ add(sp, sp, Operand(1 * kPointerSize)); | 982 __ add(sp, sp, Operand(1 * kPointerSize)); |
| 1069 __ Ret(); | 983 __ Ret(); |
| 1070 | 984 |
| 1071 __ bind(&runtime); | 985 __ bind(&runtime); |
| 1072 // Handle number to string in the runtime system if not found in the cache. | 986 // Handle number to string in the runtime system if not found in the cache. |
| 1073 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | 987 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
| 1074 } | 988 } |
| 1075 | 989 |
| 1076 | 990 |
| 1077 static void ICCompareStub_CheckInputType(MacroAssembler* masm, | 991 static void ICCompareStub_CheckInputType(MacroAssembler* masm, |
| (...skipping 4707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5785 Label* slow) { | 5699 Label* slow) { |
| 5786 // First check if the argument is already a string. | 5700 // First check if the argument is already a string. |
| 5787 Label not_string, done; | 5701 Label not_string, done; |
| 5788 __ JumpIfSmi(arg, ¬_string); | 5702 __ JumpIfSmi(arg, ¬_string); |
| 5789 __ CompareObjectType(arg, scratch1, scratch1, FIRST_NONSTRING_TYPE); | 5703 __ CompareObjectType(arg, scratch1, scratch1, FIRST_NONSTRING_TYPE); |
| 5790 __ b(lt, &done); | 5704 __ b(lt, &done); |
| 5791 | 5705 |
| 5792 // Check the number to string cache. | 5706 // Check the number to string cache. |
| 5793 __ bind(¬_string); | 5707 __ bind(¬_string); |
| 5794 // Puts the cached result into scratch1. | 5708 // Puts the cached result into scratch1. |
| 5795 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 5709 __ LookupNumberStringCache(arg, scratch1, scratch2, scratch3, scratch4, slow); |
| 5796 arg, | |
| 5797 scratch1, | |
| 5798 scratch2, | |
| 5799 scratch3, | |
| 5800 scratch4, | |
| 5801 slow); | |
| 5802 __ mov(arg, scratch1); | 5710 __ mov(arg, scratch1); |
| 5803 __ str(arg, MemOperand(sp, stack_offset)); | 5711 __ str(arg, MemOperand(sp, stack_offset)); |
| 5804 __ bind(&done); | 5712 __ bind(&done); |
| 5805 } | 5713 } |
| 5806 | 5714 |
| 5807 | 5715 |
| 5808 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 5716 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
| 5809 ASSERT(state_ == CompareIC::SMI); | 5717 ASSERT(state_ == CompareIC::SMI); |
| 5810 Label miss; | 5718 Label miss; |
| 5811 __ orr(r2, r1, r0); | 5719 __ orr(r2, r1, r0); |
| (...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7154 __ bind(&fast_elements_case); | 7062 __ bind(&fast_elements_case); |
| 7155 GenerateCase(masm, FAST_ELEMENTS); | 7063 GenerateCase(masm, FAST_ELEMENTS); |
| 7156 } | 7064 } |
| 7157 | 7065 |
| 7158 | 7066 |
| 7159 #undef __ | 7067 #undef __ |
| 7160 | 7068 |
| 7161 } } // namespace v8::internal | 7069 } } // namespace v8::internal |
| 7162 | 7070 |
| 7163 #endif // V8_TARGET_ARCH_ARM | 7071 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |