| 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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 2245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2256 // (9) Sliced string. Replace subject with parent. Go to (4). | 2256 // (9) Sliced string. Replace subject with parent. Go to (4). |
| 2257 // Load offset into r9 and replace subject string with parent. | 2257 // Load offset into r9 and replace subject string with parent. |
| 2258 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2258 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
| 2259 __ SmiUntag(r9); | 2259 __ SmiUntag(r9); |
| 2260 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2260 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
| 2261 __ jmp(&check_underlying); // Go to (4). | 2261 __ jmp(&check_underlying); // Go to (4). |
| 2262 #endif // V8_INTERPRETED_REGEXP | 2262 #endif // V8_INTERPRETED_REGEXP |
| 2263 } | 2263 } |
| 2264 | 2264 |
| 2265 | 2265 |
| 2266 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 2266 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
| 2267 bool is_super) { | |
| 2268 // r0 : number of arguments to the construct function | 2267 // r0 : number of arguments to the construct function |
| 2269 // r1 : the function to call | 2268 // r1 : the function to call |
| 2270 // r2 : feedback vector | 2269 // r2 : feedback vector |
| 2271 // r3 : slot in feedback vector (Smi) | 2270 // r3 : slot in feedback vector (Smi) |
| 2272 // r4 : new target (for IsSuperConstructorCall) | |
| 2273 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2271 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 2274 | 2272 |
| 2275 // Number-of-arguments register must be smi-tagged to call out. | 2273 // Number-of-arguments register must be smi-tagged to call out. |
| 2276 __ SmiTag(r0); | 2274 __ SmiTag(r0); |
| 2277 __ Push(r3, r2, r1, r0); | 2275 __ Push(r3, r2, r1, r0); |
| 2278 if (is_super) { | |
| 2279 __ Push(r4); | |
| 2280 } | |
| 2281 | 2276 |
| 2282 __ CallStub(stub); | 2277 __ CallStub(stub); |
| 2283 | 2278 |
| 2284 if (is_super) { | |
| 2285 __ Pop(r4); | |
| 2286 } | |
| 2287 __ Pop(r3, r2, r1, r0); | 2279 __ Pop(r3, r2, r1, r0); |
| 2288 __ SmiUntag(r0); | 2280 __ SmiUntag(r0); |
| 2289 } | 2281 } |
| 2290 | 2282 |
| 2291 | 2283 |
| 2292 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { | 2284 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 2293 // Cache the called function in a feedback vector slot. Cache states | 2285 // Cache the called function in a feedback vector slot. Cache states |
| 2294 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2286 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 2295 // megamorphic. | 2287 // megamorphic. |
| 2296 // r0 : number of arguments to the construct function | 2288 // r0 : number of arguments to the construct function |
| 2297 // r1 : the function to call | 2289 // r1 : the function to call |
| 2298 // r2 : feedback vector | 2290 // r2 : feedback vector |
| 2299 // r3 : slot in feedback vector (Smi) | 2291 // r3 : slot in feedback vector (Smi) |
| 2300 // r4 : new target (for IsSuperConstructorCall) | |
| 2301 Label initialize, done, miss, megamorphic, not_array_function; | 2292 Label initialize, done, miss, megamorphic, not_array_function; |
| 2302 | 2293 |
| 2303 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2294 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
| 2304 masm->isolate()->heap()->megamorphic_symbol()); | 2295 masm->isolate()->heap()->megamorphic_symbol()); |
| 2305 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2296 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
| 2306 masm->isolate()->heap()->uninitialized_symbol()); | 2297 masm->isolate()->heap()->uninitialized_symbol()); |
| 2307 | 2298 |
| 2308 // Load the cache state into r5. | 2299 // Load the cache state into r5. |
| 2309 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2300 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 2310 __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 2301 __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2362 | 2353 |
| 2363 // Make sure the function is the Array() function | 2354 // Make sure the function is the Array() function |
| 2364 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5); | 2355 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5); |
| 2365 __ cmp(r1, r5); | 2356 __ cmp(r1, r5); |
| 2366 __ b(ne, ¬_array_function); | 2357 __ b(ne, ¬_array_function); |
| 2367 | 2358 |
| 2368 // The target function is the Array constructor, | 2359 // The target function is the Array constructor, |
| 2369 // Create an AllocationSite if we don't already have it, store it in the | 2360 // Create an AllocationSite if we don't already have it, store it in the |
| 2370 // slot. | 2361 // slot. |
| 2371 CreateAllocationSiteStub create_stub(masm->isolate()); | 2362 CreateAllocationSiteStub create_stub(masm->isolate()); |
| 2372 CallStubInRecordCallTarget(masm, &create_stub, is_super); | 2363 CallStubInRecordCallTarget(masm, &create_stub); |
| 2373 __ b(&done); | 2364 __ b(&done); |
| 2374 | 2365 |
| 2375 __ bind(¬_array_function); | 2366 __ bind(¬_array_function); |
| 2376 CreateWeakCellStub weak_cell_stub(masm->isolate()); | 2367 CreateWeakCellStub weak_cell_stub(masm->isolate()); |
| 2377 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2368 CallStubInRecordCallTarget(masm, &weak_cell_stub); |
| 2378 __ bind(&done); | 2369 __ bind(&done); |
| 2379 } | 2370 } |
| 2380 | 2371 |
| 2381 | 2372 |
| 2382 void CallConstructStub::Generate(MacroAssembler* masm) { | 2373 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 2383 // r0 : number of arguments | 2374 // r0 : number of arguments |
| 2384 // r1 : the function to call | 2375 // r1 : the function to call |
| 2385 // r2 : feedback vector | 2376 // r2 : feedback vector |
| 2386 // r3 : slot in feedback vector (Smi, for RecordCallTarget) | 2377 // r3 : slot in feedback vector (Smi, for RecordCallTarget) |
| 2387 // r4 : new target (for IsSuperConstructorCall) | |
| 2388 | 2378 |
| 2389 Label non_function; | 2379 Label non_function; |
| 2390 // Check that the function is not a smi. | 2380 // Check that the function is not a smi. |
| 2391 __ JumpIfSmi(r1, &non_function); | 2381 __ JumpIfSmi(r1, &non_function); |
| 2392 // Check that the function is a JSFunction. | 2382 // Check that the function is a JSFunction. |
| 2393 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); | 2383 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); |
| 2394 __ b(ne, &non_function); | 2384 __ b(ne, &non_function); |
| 2395 | 2385 |
| 2396 if (RecordCallTarget()) { | 2386 GenerateRecordCallTarget(masm); |
| 2397 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); | |
| 2398 | 2387 |
| 2399 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2388 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 2400 Label feedback_register_initialized; | 2389 Label feedback_register_initialized; |
| 2401 // Put the AllocationSite from the feedback vector into r2, or undefined. | 2390 // Put the AllocationSite from the feedback vector into r2, or undefined. |
| 2402 __ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 2391 __ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize)); |
| 2403 __ ldr(r5, FieldMemOperand(r2, AllocationSite::kMapOffset)); | 2392 __ ldr(r5, FieldMemOperand(r2, AllocationSite::kMapOffset)); |
| 2404 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | 2393 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 2405 __ b(eq, &feedback_register_initialized); | 2394 __ b(eq, &feedback_register_initialized); |
| 2406 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 2395 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 2407 __ bind(&feedback_register_initialized); | 2396 __ bind(&feedback_register_initialized); |
| 2408 | 2397 |
| 2409 __ AssertUndefinedOrAllocationSite(r2, r5); | 2398 __ AssertUndefinedOrAllocationSite(r2, r5); |
| 2410 } | |
| 2411 | 2399 |
| 2412 // Pass function as new target. | 2400 // Pass function as new target. |
| 2413 if (IsSuperConstructorCall()) { | 2401 __ mov(r3, r1); |
| 2414 __ mov(r3, r4); | |
| 2415 } else { | |
| 2416 __ mov(r3, r1); | |
| 2417 } | |
| 2418 | 2402 |
| 2419 // Tail call to the function-specific construct stub (still in the caller | 2403 // Tail call to the function-specific construct stub (still in the caller |
| 2420 // context at this point). | 2404 // context at this point). |
| 2421 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 2405 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 2422 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); | 2406 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); |
| 2423 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2407 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2424 | 2408 |
| 2425 __ bind(&non_function); | 2409 __ bind(&non_function); |
| 2426 __ mov(r3, r1); | 2410 __ mov(r3, r1); |
| 2427 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2411 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| (...skipping 2960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5388 MemOperand(fp, 6 * kPointerSize), NULL); | 5372 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5389 } | 5373 } |
| 5390 | 5374 |
| 5391 | 5375 |
| 5392 #undef __ | 5376 #undef __ |
| 5393 | 5377 |
| 5394 } // namespace internal | 5378 } // namespace internal |
| 5395 } // namespace v8 | 5379 } // namespace v8 |
| 5396 | 5380 |
| 5397 #endif // V8_TARGET_ARCH_ARM | 5381 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |