OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 2158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2169 | 2169 |
2170 Register arguments_list = x0; | 2170 Register arguments_list = x0; |
2171 Register target = x1; | 2171 Register target = x1; |
2172 Register new_target = x3; | 2172 Register new_target = x3; |
2173 | 2173 |
2174 Register args = x0; | 2174 Register args = x0; |
2175 Register len = x2; | 2175 Register len = x2; |
2176 | 2176 |
2177 // Create the list of arguments from the array-like argumentsList. | 2177 // Create the list of arguments from the array-like argumentsList. |
2178 { | 2178 { |
2179 Label create_arguments, create_array, create_runtime, done_create; | 2179 Label create_arguments, create_array, create_holey_array, create_runtime, |
| 2180 done_create; |
2180 __ JumpIfSmi(arguments_list, &create_runtime); | 2181 __ JumpIfSmi(arguments_list, &create_runtime); |
2181 | 2182 |
2182 // Load native context. | 2183 // Load native context. |
2183 Register native_context = x4; | 2184 Register native_context = x4; |
2184 __ Ldr(native_context, NativeContextMemOperand()); | 2185 __ Ldr(native_context, NativeContextMemOperand()); |
2185 | 2186 |
2186 // Load the map of argumentsList. | 2187 // Load the map of argumentsList. |
2187 Register arguments_list_map = x2; | 2188 Register arguments_list_map = x2; |
2188 __ Ldr(arguments_list_map, | 2189 __ Ldr(arguments_list_map, |
2189 FieldMemOperand(arguments_list, HeapObject::kMapOffset)); | 2190 FieldMemOperand(arguments_list, HeapObject::kMapOffset)); |
2190 | 2191 |
2191 // Check if argumentsList is an (unmodified) arguments object. | 2192 // Check if argumentsList is an (unmodified) arguments object. |
2192 __ Ldr(x10, ContextMemOperand(native_context, | 2193 __ Ldr(x10, ContextMemOperand(native_context, |
2193 Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | 2194 Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
2194 __ Ldr(x11, ContextMemOperand(native_context, | 2195 __ Ldr(x11, ContextMemOperand(native_context, |
2195 Context::STRICT_ARGUMENTS_MAP_INDEX)); | 2196 Context::STRICT_ARGUMENTS_MAP_INDEX)); |
2196 __ Cmp(arguments_list_map, x10); | 2197 __ Cmp(arguments_list_map, x10); |
2197 __ Ccmp(arguments_list_map, x11, ZFlag, ne); | 2198 __ Ccmp(arguments_list_map, x11, ZFlag, ne); |
2198 __ B(eq, &create_arguments); | 2199 __ B(eq, &create_arguments); |
2199 | 2200 |
2200 // Check if argumentsList is a fast JSArray. | 2201 // Check if argumentsList is a fast JSArray. |
2201 __ CompareInstanceType(arguments_list_map, native_context, JS_ARRAY_TYPE); | 2202 __ CompareInstanceType(arguments_list_map, x10, JS_ARRAY_TYPE); |
2202 __ B(eq, &create_array); | 2203 __ B(eq, &create_array); |
2203 | 2204 |
2204 // Ask the runtime to create the list (actually a FixedArray). | 2205 // Ask the runtime to create the list (actually a FixedArray). |
2205 __ Bind(&create_runtime); | 2206 __ Bind(&create_runtime); |
2206 { | 2207 { |
2207 FrameScope scope(masm, StackFrame::INTERNAL); | 2208 FrameScope scope(masm, StackFrame::INTERNAL); |
2208 __ Push(target, new_target, arguments_list); | 2209 __ Push(target, new_target, arguments_list); |
2209 __ CallRuntime(Runtime::kCreateListFromArrayLike); | 2210 __ CallRuntime(Runtime::kCreateListFromArrayLike); |
2210 __ Pop(new_target, target); | 2211 __ Pop(new_target, target); |
2211 __ Ldrsw(len, UntagSmiFieldMemOperand(arguments_list, | 2212 __ Ldrsw(len, UntagSmiFieldMemOperand(arguments_list, |
2212 FixedArray::kLengthOffset)); | 2213 FixedArray::kLengthOffset)); |
2213 } | 2214 } |
2214 __ B(&done_create); | 2215 __ B(&done_create); |
2215 | 2216 |
2216 // Try to create the list from an arguments object. | 2217 // Try to create the list from an arguments object. |
2217 __ Bind(&create_arguments); | 2218 __ Bind(&create_arguments); |
2218 __ Ldrsw(len, UntagSmiFieldMemOperand(arguments_list, | 2219 __ Ldrsw(len, UntagSmiFieldMemOperand(arguments_list, |
2219 JSArgumentsObject::kLengthOffset)); | 2220 JSArgumentsObject::kLengthOffset)); |
2220 __ Ldr(x10, FieldMemOperand(arguments_list, JSObject::kElementsOffset)); | 2221 __ Ldr(x10, FieldMemOperand(arguments_list, JSObject::kElementsOffset)); |
2221 __ Ldrsw(x11, UntagSmiFieldMemOperand(x10, FixedArray::kLengthOffset)); | 2222 __ Ldrsw(x11, UntagSmiFieldMemOperand(x10, FixedArray::kLengthOffset)); |
2222 __ CompareAndBranch(len, x11, ne, &create_runtime); | 2223 __ CompareAndBranch(len, x11, ne, &create_runtime); |
2223 __ Mov(args, x10); | 2224 __ Mov(args, x10); |
2224 __ B(&done_create); | 2225 __ B(&done_create); |
2225 | 2226 |
| 2227 // For holey JSArrays we need to check that the array prototype chain |
| 2228 // protector is intact and our prototype is the Array.prototype actually. |
| 2229 __ Bind(&create_holey_array); |
| 2230 // -- x2 : arguments_list_map |
| 2231 // -- x4 : native_context |
| 2232 Register arguments_list_prototype = x2; |
| 2233 __ Ldr(arguments_list_prototype, |
| 2234 FieldMemOperand(arguments_list_map, Map::kPrototypeOffset)); |
| 2235 __ Ldr(x10, ContextMemOperand(native_context, |
| 2236 Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); |
| 2237 __ Cmp(arguments_list_prototype, x10); |
| 2238 __ B(ne, &create_runtime); |
| 2239 __ LoadRoot(x10, Heap::kArrayProtectorRootIndex); |
| 2240 __ Ldrsw(x11, UntagSmiFieldMemOperand(x10, PropertyCell::kValueOffset)); |
| 2241 __ Cmp(x11, Isolate::kProtectorValid); |
| 2242 __ B(ne, &create_runtime); |
| 2243 __ Ldrsw(len, |
| 2244 UntagSmiFieldMemOperand(arguments_list, JSArray::kLengthOffset)); |
| 2245 __ Ldr(args, FieldMemOperand(arguments_list, JSArray::kElementsOffset)); |
| 2246 __ B(&done_create); |
| 2247 |
2226 // Try to create the list from a JSArray object. | 2248 // Try to create the list from a JSArray object. |
2227 __ Bind(&create_array); | 2249 __ Bind(&create_array); |
2228 __ Ldr(x10, FieldMemOperand(arguments_list_map, Map::kBitField2Offset)); | 2250 __ Ldr(x10, FieldMemOperand(arguments_list_map, Map::kBitField2Offset)); |
2229 __ DecodeField<Map::ElementsKindBits>(x10); | 2251 __ DecodeField<Map::ElementsKindBits>(x10); |
2230 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2252 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
| 2253 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
2231 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2254 STATIC_ASSERT(FAST_ELEMENTS == 2); |
2232 // Branch for anything that's not FAST_{SMI_}ELEMENTS. | 2255 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
2233 __ TestAndBranchIfAnySet(x10, ~FAST_ELEMENTS, &create_runtime); | 2256 // Check if it is a holey array, the order of the cmp is important as |
| 2257 // anything higher than FAST_HOLEY_ELEMENTS will fall back to runtime. |
| 2258 __ Cmp(x10, FAST_HOLEY_ELEMENTS); |
| 2259 __ B(hi, &create_runtime); |
| 2260 // Only FAST_XXX after this point, FAST_HOLEY_XXX are odd values. |
| 2261 __ Tbnz(x10, 0, &create_holey_array); |
| 2262 // FAST_SMI_ELEMENTS or FAST_ELEMENTS after this point. |
2234 __ Ldrsw(len, | 2263 __ Ldrsw(len, |
2235 UntagSmiFieldMemOperand(arguments_list, JSArray::kLengthOffset)); | 2264 UntagSmiFieldMemOperand(arguments_list, JSArray::kLengthOffset)); |
2236 __ Ldr(args, FieldMemOperand(arguments_list, JSArray::kElementsOffset)); | 2265 __ Ldr(args, FieldMemOperand(arguments_list, JSArray::kElementsOffset)); |
2237 | 2266 |
2238 __ Bind(&done_create); | 2267 __ Bind(&done_create); |
2239 } | 2268 } |
2240 | 2269 |
2241 // Check for stack overflow. | 2270 // Check for stack overflow. |
2242 { | 2271 { |
2243 // Check the stack for overflow. We are not trying to catch interruptions | 2272 // Check the stack for overflow. We are not trying to catch interruptions |
(...skipping 13 matching lines...) Expand all Loading... |
2257 // ----------- S t a t e ------------- | 2286 // ----------- S t a t e ------------- |
2258 // -- x0 : args (a FixedArray built from argumentsList) | 2287 // -- x0 : args (a FixedArray built from argumentsList) |
2259 // -- x1 : target | 2288 // -- x1 : target |
2260 // -- x2 : len (number of elements to push from args) | 2289 // -- x2 : len (number of elements to push from args) |
2261 // -- x3 : new.target (checked to be constructor or undefined) | 2290 // -- x3 : new.target (checked to be constructor or undefined) |
2262 // -- jssp[0] : thisArgument | 2291 // -- jssp[0] : thisArgument |
2263 // ----------------------------------- | 2292 // ----------------------------------- |
2264 | 2293 |
2265 // Push arguments onto the stack (thisArgument is already on the stack). | 2294 // Push arguments onto the stack (thisArgument is already on the stack). |
2266 { | 2295 { |
2267 Label done, loop; | 2296 Label done, push, loop; |
2268 Register src = x4; | 2297 Register src = x4; |
2269 | 2298 |
2270 __ Add(src, args, FixedArray::kHeaderSize - kHeapObjectTag); | 2299 __ Add(src, args, FixedArray::kHeaderSize - kHeapObjectTag); |
2271 __ Mov(x0, len); // The 'len' argument for Call() or Construct(). | 2300 __ Mov(x0, len); // The 'len' argument for Call() or Construct(). |
2272 __ Cbz(len, &done); | 2301 __ Cbz(len, &done); |
| 2302 Register the_hole_value = x11; |
| 2303 Register undefined_value = x12; |
| 2304 // We do not use the CompareRoot macro as it would do a LoadRoot behind the |
| 2305 // scenes and we want to avoid that in a loop. |
| 2306 __ LoadRoot(the_hole_value, Heap::kTheHoleValueRootIndex); |
| 2307 __ LoadRoot(undefined_value, Heap::kUndefinedValueRootIndex); |
2273 __ Claim(len); | 2308 __ Claim(len); |
2274 __ Bind(&loop); | 2309 __ Bind(&loop); |
2275 __ Sub(len, len, 1); | 2310 __ Sub(len, len, 1); |
2276 __ Ldr(x10, MemOperand(src, kPointerSize, PostIndex)); | 2311 __ Ldr(x10, MemOperand(src, kPointerSize, PostIndex)); |
| 2312 __ Cmp(x10, the_hole_value); |
| 2313 __ Csel(x10, x10, undefined_value, ne); |
2277 __ Poke(x10, Operand(len, LSL, kPointerSizeLog2)); | 2314 __ Poke(x10, Operand(len, LSL, kPointerSizeLog2)); |
2278 __ Cbnz(len, &loop); | 2315 __ Cbnz(len, &loop); |
2279 __ Bind(&done); | 2316 __ Bind(&done); |
2280 } | 2317 } |
2281 | 2318 |
2282 // ----------- S t a t e ------------- | 2319 // ----------- S t a t e ------------- |
2283 // -- x0 : argument count (len) | 2320 // -- x0 : argument count (len) |
2284 // -- x1 : target | 2321 // -- x1 : target |
2285 // -- x3 : new.target (checked to be constructor or undefined) | 2322 // -- x3 : new.target (checked to be constructor or undefined) |
2286 // -- jssp[0] : args[len-1] | 2323 // -- jssp[0] : args[len-1] |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2967 __ Unreachable(); | 3004 __ Unreachable(); |
2968 } | 3005 } |
2969 } | 3006 } |
2970 | 3007 |
2971 #undef __ | 3008 #undef __ |
2972 | 3009 |
2973 } // namespace internal | 3010 } // namespace internal |
2974 } // namespace v8 | 3011 } // namespace v8 |
2975 | 3012 |
2976 #endif // V8_TARGET_ARCH_ARM | 3013 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |