OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 2063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 DCHECK(bits_operand.instructions_required(this) == 1); | 2074 DCHECK(bits_operand.instructions_required(this) == 1); |
2075 add(result_end, source, bits_operand, LeaveCC, cond); | 2075 add(result_end, source, bits_operand, LeaveCC, cond); |
2076 source = result_end; | 2076 source = result_end; |
2077 cond = cc; | 2077 cond = cc; |
2078 } | 2078 } |
2079 } | 2079 } |
2080 cmp(result_end, Operand(alloc_limit)); | 2080 cmp(result_end, Operand(alloc_limit)); |
2081 b(hi, gc_required); | 2081 b(hi, gc_required); |
2082 str(result_end, MemOperand(top_address)); | 2082 str(result_end, MemOperand(top_address)); |
2083 | 2083 |
2084 // Tag object if requested. | 2084 // Tag object. |
2085 if ((flags & TAG_OBJECT) != 0) { | 2085 add(result, result, Operand(kHeapObjectTag)); |
2086 add(result, result, Operand(kHeapObjectTag)); | |
2087 } | |
2088 } | 2086 } |
2089 | 2087 |
2090 | 2088 |
2091 void MacroAssembler::Allocate(Register object_size, Register result, | 2089 void MacroAssembler::Allocate(Register object_size, Register result, |
2092 Register result_end, Register scratch, | 2090 Register result_end, Register scratch, |
2093 Label* gc_required, AllocationFlags flags) { | 2091 Label* gc_required, AllocationFlags flags) { |
2094 if (!FLAG_inline_new) { | 2092 if (!FLAG_inline_new) { |
2095 if (emit_debug_code()) { | 2093 if (emit_debug_code()) { |
2096 // Trash the registers to simulate an allocation failure. | 2094 // Trash the registers to simulate an allocation failure. |
2097 mov(result, Operand(0x7091)); | 2095 mov(result, Operand(0x7091)); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2170 cmp(result_end, Operand(alloc_limit)); | 2168 cmp(result_end, Operand(alloc_limit)); |
2171 b(hi, gc_required); | 2169 b(hi, gc_required); |
2172 | 2170 |
2173 // Update allocation top. result temporarily holds the new top. | 2171 // Update allocation top. result temporarily holds the new top. |
2174 if (emit_debug_code()) { | 2172 if (emit_debug_code()) { |
2175 tst(result_end, Operand(kObjectAlignmentMask)); | 2173 tst(result_end, Operand(kObjectAlignmentMask)); |
2176 Check(eq, kUnalignedAllocationInNewSpace); | 2174 Check(eq, kUnalignedAllocationInNewSpace); |
2177 } | 2175 } |
2178 str(result_end, MemOperand(top_address)); | 2176 str(result_end, MemOperand(top_address)); |
2179 | 2177 |
2180 // Tag object if requested. | 2178 // Tag object. |
2181 if ((flags & TAG_OBJECT) != 0) { | 2179 add(result, result, Operand(kHeapObjectTag)); |
2182 add(result, result, Operand(kHeapObjectTag)); | |
2183 } | |
2184 } | 2180 } |
2185 | 2181 |
2186 | 2182 |
2187 void MacroAssembler::AllocateTwoByteString(Register result, | 2183 void MacroAssembler::AllocateTwoByteString(Register result, |
2188 Register length, | 2184 Register length, |
2189 Register scratch1, | 2185 Register scratch1, |
2190 Register scratch2, | 2186 Register scratch2, |
2191 Register scratch3, | 2187 Register scratch3, |
2192 Label* gc_required) { | 2188 Label* gc_required) { |
2193 // Calculate the number of bytes needed for the characters in the string while | 2189 // Calculate the number of bytes needed for the characters in the string while |
2194 // observing object alignment. | 2190 // observing object alignment. |
2195 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 2191 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
2196 mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars. | 2192 mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars. |
2197 add(scratch1, scratch1, | 2193 add(scratch1, scratch1, |
2198 Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); | 2194 Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); |
2199 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 2195 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
2200 | 2196 |
2201 // Allocate two-byte string in new space. | 2197 // Allocate two-byte string in new space. |
2202 Allocate(scratch1, | 2198 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
2203 result, | 2199 NO_ALLOCATION_FLAGS); |
2204 scratch2, | |
2205 scratch3, | |
2206 gc_required, | |
2207 TAG_OBJECT); | |
2208 | 2200 |
2209 // Set the map, length and hash field. | 2201 // Set the map, length and hash field. |
2210 InitializeNewString(result, | 2202 InitializeNewString(result, |
2211 length, | 2203 length, |
2212 Heap::kStringMapRootIndex, | 2204 Heap::kStringMapRootIndex, |
2213 scratch1, | 2205 scratch1, |
2214 scratch2); | 2206 scratch2); |
2215 } | 2207 } |
2216 | 2208 |
2217 | 2209 |
2218 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 2210 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
2219 Register scratch1, Register scratch2, | 2211 Register scratch1, Register scratch2, |
2220 Register scratch3, | 2212 Register scratch3, |
2221 Label* gc_required) { | 2213 Label* gc_required) { |
2222 // Calculate the number of bytes needed for the characters in the string while | 2214 // Calculate the number of bytes needed for the characters in the string while |
2223 // observing object alignment. | 2215 // observing object alignment. |
2224 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 2216 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
2225 DCHECK(kCharSize == 1); | 2217 DCHECK(kCharSize == 1); |
2226 add(scratch1, length, | 2218 add(scratch1, length, |
2227 Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); | 2219 Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); |
2228 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 2220 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
2229 | 2221 |
2230 // Allocate one-byte string in new space. | 2222 // Allocate one-byte string in new space. |
2231 Allocate(scratch1, | 2223 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
2232 result, | 2224 NO_ALLOCATION_FLAGS); |
2233 scratch2, | |
2234 scratch3, | |
2235 gc_required, | |
2236 TAG_OBJECT); | |
2237 | 2225 |
2238 // Set the map, length and hash field. | 2226 // Set the map, length and hash field. |
2239 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, | 2227 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, |
2240 scratch1, scratch2); | 2228 scratch1, scratch2); |
2241 } | 2229 } |
2242 | 2230 |
2243 | 2231 |
2244 void MacroAssembler::AllocateTwoByteConsString(Register result, | 2232 void MacroAssembler::AllocateTwoByteConsString(Register result, |
2245 Register length, | 2233 Register length, |
2246 Register scratch1, | 2234 Register scratch1, |
2247 Register scratch2, | 2235 Register scratch2, |
2248 Label* gc_required) { | 2236 Label* gc_required) { |
2249 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 2237 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
2250 TAG_OBJECT); | 2238 NO_ALLOCATION_FLAGS); |
2251 | 2239 |
2252 InitializeNewString(result, | 2240 InitializeNewString(result, |
2253 length, | 2241 length, |
2254 Heap::kConsStringMapRootIndex, | 2242 Heap::kConsStringMapRootIndex, |
2255 scratch1, | 2243 scratch1, |
2256 scratch2); | 2244 scratch2); |
2257 } | 2245 } |
2258 | 2246 |
2259 | 2247 |
2260 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, | 2248 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, |
2261 Register scratch1, | 2249 Register scratch1, |
2262 Register scratch2, | 2250 Register scratch2, |
2263 Label* gc_required) { | 2251 Label* gc_required) { |
2264 Allocate(ConsString::kSize, | 2252 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
2265 result, | 2253 NO_ALLOCATION_FLAGS); |
2266 scratch1, | |
2267 scratch2, | |
2268 gc_required, | |
2269 TAG_OBJECT); | |
2270 | 2254 |
2271 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, | 2255 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, |
2272 scratch1, scratch2); | 2256 scratch1, scratch2); |
2273 } | 2257 } |
2274 | 2258 |
2275 | 2259 |
2276 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 2260 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
2277 Register length, | 2261 Register length, |
2278 Register scratch1, | 2262 Register scratch1, |
2279 Register scratch2, | 2263 Register scratch2, |
2280 Label* gc_required) { | 2264 Label* gc_required) { |
2281 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 2265 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
2282 TAG_OBJECT); | 2266 NO_ALLOCATION_FLAGS); |
2283 | 2267 |
2284 InitializeNewString(result, | 2268 InitializeNewString(result, |
2285 length, | 2269 length, |
2286 Heap::kSlicedStringMapRootIndex, | 2270 Heap::kSlicedStringMapRootIndex, |
2287 scratch1, | 2271 scratch1, |
2288 scratch2); | 2272 scratch2); |
2289 } | 2273 } |
2290 | 2274 |
2291 | 2275 |
2292 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 2276 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
2293 Register length, | 2277 Register length, |
2294 Register scratch1, | 2278 Register scratch1, |
2295 Register scratch2, | 2279 Register scratch2, |
2296 Label* gc_required) { | 2280 Label* gc_required) { |
2297 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 2281 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
2298 TAG_OBJECT); | 2282 NO_ALLOCATION_FLAGS); |
2299 | 2283 |
2300 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, | 2284 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, |
2301 scratch1, scratch2); | 2285 scratch1, scratch2); |
2302 } | 2286 } |
2303 | 2287 |
2304 | 2288 |
2305 void MacroAssembler::CompareObjectType(Register object, | 2289 void MacroAssembler::CompareObjectType(Register object, |
2306 Register map, | 2290 Register map, |
2307 Register type_reg, | 2291 Register type_reg, |
2308 InstanceType type) { | 2292 InstanceType type) { |
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3204 } | 3188 } |
3205 | 3189 |
3206 | 3190 |
3207 // Allocates a heap number or jumps to the need_gc label if the young space | 3191 // Allocates a heap number or jumps to the need_gc label if the young space |
3208 // is full and a scavenge is needed. | 3192 // is full and a scavenge is needed. |
3209 void MacroAssembler::AllocateHeapNumber(Register result, | 3193 void MacroAssembler::AllocateHeapNumber(Register result, |
3210 Register scratch1, | 3194 Register scratch1, |
3211 Register scratch2, | 3195 Register scratch2, |
3212 Register heap_number_map, | 3196 Register heap_number_map, |
3213 Label* gc_required, | 3197 Label* gc_required, |
3214 TaggingMode tagging_mode, | |
3215 MutableMode mode) { | 3198 MutableMode mode) { |
3216 // Allocate an object in the heap for the heap number and tag it as a heap | 3199 // Allocate an object in the heap for the heap number and tag it as a heap |
3217 // object. | 3200 // object. |
3218 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, | 3201 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, |
3219 tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS); | 3202 NO_ALLOCATION_FLAGS); |
3220 | 3203 |
3221 Heap::RootListIndex map_index = mode == MUTABLE | 3204 Heap::RootListIndex map_index = mode == MUTABLE |
3222 ? Heap::kMutableHeapNumberMapRootIndex | 3205 ? Heap::kMutableHeapNumberMapRootIndex |
3223 : Heap::kHeapNumberMapRootIndex; | 3206 : Heap::kHeapNumberMapRootIndex; |
3224 AssertIsRoot(heap_number_map, map_index); | 3207 AssertIsRoot(heap_number_map, map_index); |
3225 | 3208 |
3226 // Store heap number map in the allocated object. | 3209 // Store heap number map in the allocated object. |
3227 if (tagging_mode == TAG_RESULT) { | 3210 str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); |
3228 str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); | |
3229 } else { | |
3230 str(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); | |
3231 } | |
3232 } | 3211 } |
3233 | 3212 |
3234 | 3213 |
3235 void MacroAssembler::AllocateHeapNumberWithValue(Register result, | 3214 void MacroAssembler::AllocateHeapNumberWithValue(Register result, |
3236 DwVfpRegister value, | 3215 DwVfpRegister value, |
3237 Register scratch1, | 3216 Register scratch1, |
3238 Register scratch2, | 3217 Register scratch2, |
3239 Register heap_number_map, | 3218 Register heap_number_map, |
3240 Label* gc_required) { | 3219 Label* gc_required) { |
3241 AllocateHeapNumber(result, scratch1, scratch2, heap_number_map, gc_required); | 3220 AllocateHeapNumber(result, scratch1, scratch2, heap_number_map, gc_required); |
3242 sub(scratch1, result, Operand(kHeapObjectTag)); | 3221 sub(scratch1, result, Operand(kHeapObjectTag)); |
3243 vstr(value, scratch1, HeapNumber::kValueOffset); | 3222 vstr(value, scratch1, HeapNumber::kValueOffset); |
3244 } | 3223 } |
3245 | 3224 |
3246 | 3225 |
3247 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 3226 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
3248 Register value, Register scratch1, | 3227 Register value, Register scratch1, |
3249 Register scratch2, Label* gc_required) { | 3228 Register scratch2, Label* gc_required) { |
3250 DCHECK(!result.is(constructor)); | 3229 DCHECK(!result.is(constructor)); |
3251 DCHECK(!result.is(scratch1)); | 3230 DCHECK(!result.is(scratch1)); |
3252 DCHECK(!result.is(scratch2)); | 3231 DCHECK(!result.is(scratch2)); |
3253 DCHECK(!result.is(value)); | 3232 DCHECK(!result.is(value)); |
3254 | 3233 |
3255 // Allocate JSValue in new space. | 3234 // Allocate JSValue in new space. |
3256 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, TAG_OBJECT); | 3235 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, |
| 3236 NO_ALLOCATION_FLAGS); |
3257 | 3237 |
3258 // Initialize the JSValue. | 3238 // Initialize the JSValue. |
3259 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); | 3239 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); |
3260 str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); | 3240 str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); |
3261 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); | 3241 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); |
3262 str(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); | 3242 str(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); |
3263 str(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); | 3243 str(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); |
3264 str(value, FieldMemOperand(result, JSValue::kValueOffset)); | 3244 str(value, FieldMemOperand(result, JSValue::kValueOffset)); |
3265 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 3245 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
3266 } | 3246 } |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3945 } | 3925 } |
3946 } | 3926 } |
3947 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3927 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
3948 add(result, result, Operand(dividend, LSR, 31)); | 3928 add(result, result, Operand(dividend, LSR, 31)); |
3949 } | 3929 } |
3950 | 3930 |
3951 } // namespace internal | 3931 } // namespace internal |
3952 } // namespace v8 | 3932 } // namespace v8 |
3953 | 3933 |
3954 #endif // V8_TARGET_ARCH_ARM | 3934 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |