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 |