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 "src/v8.h" | 5 #include "src/v8.h" |
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/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2360 // (9) Sliced string. Replace subject with parent. Go to (4). | 2360 // (9) Sliced string. Replace subject with parent. Go to (4). |
2361 // Load offset into r9 and replace subject string with parent. | 2361 // Load offset into r9 and replace subject string with parent. |
2362 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2362 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
2363 __ SmiUntag(r9); | 2363 __ SmiUntag(r9); |
2364 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2364 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
2365 __ jmp(&check_underlying); // Go to (4). | 2365 __ jmp(&check_underlying); // Go to (4). |
2366 #endif // V8_INTERPRETED_REGEXP | 2366 #endif // V8_INTERPRETED_REGEXP |
2367 } | 2367 } |
2368 | 2368 |
2369 | 2369 |
2370 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | |
2371 // r0 : number of arguments to the construct function | |
2372 // r2 : Feedback vector | |
2373 // r3 : slot in feedback vector (Smi) | |
2374 // r1 : the function to call | |
2375 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
2376 | |
2377 // Arguments register must be smi-tagged to call out. | |
Erik Corry
2015/04/02 12:54:11
Comment clarification propopsal:
Arguments registe
| |
2378 __ SmiTag(r0); | |
2379 __ Push(r3, r2, r1, r0); | |
2380 | |
2381 __ CallStub(stub); | |
2382 | |
2383 __ Pop(r3, r2, r1, r0); | |
2384 __ SmiUntag(r0); | |
2385 } | |
2386 | |
2387 | |
2370 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2388 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
2371 // Cache the called function in a feedback vector slot. Cache states | 2389 // Cache the called function in a feedback vector slot. Cache states |
2372 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2390 // are uninitialized, monomorphic (indicated by a JSFunction), and |
2373 // megamorphic. | 2391 // megamorphic. |
2374 // r0 : number of arguments to the construct function | 2392 // r0 : number of arguments to the construct function |
2375 // r1 : the function to call | 2393 // r1 : the function to call |
2376 // r2 : Feedback vector | 2394 // r2 : Feedback vector |
2377 // r3 : slot in feedback vector (Smi) | 2395 // r3 : slot in feedback vector (Smi) |
2378 Label initialize, done, miss, megamorphic, not_array_function; | 2396 Label initialize, done, miss, megamorphic, not_array_function; |
2379 | 2397 |
2380 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2398 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2381 masm->isolate()->heap()->megamorphic_symbol()); | 2399 masm->isolate()->heap()->megamorphic_symbol()); |
2382 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2400 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2383 masm->isolate()->heap()->uninitialized_symbol()); | 2401 masm->isolate()->heap()->uninitialized_symbol()); |
2384 | 2402 |
2385 // Load the cache state into r4. | 2403 // Load the cache state into r4. |
2386 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2404 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
2387 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 2405 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
2388 | 2406 |
2389 // A monomorphic cache hit or an already megamorphic state: invoke the | 2407 // A monomorphic cache hit or an already megamorphic state: invoke the |
2390 // function without changing the state. | 2408 // function without changing the state. |
2391 __ cmp(r4, r1); | 2409 Label check_allocation_site; |
2410 Register feedback_map = r5; | |
2411 Register weak_value = r8; | |
2412 __ ldr(weak_value, FieldMemOperand(r4, WeakCell::kValueOffset)); | |
2413 __ cmp(r1, weak_value); | |
2392 __ b(eq, &done); | 2414 __ b(eq, &done); |
2415 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); | |
Erik Corry
2015/04/02 12:54:11
We just treated r4 as a weak cell (3 lines up), no
mvstanton
2015/04/02 14:00:38
Correct, but it's not random. It's a performance o
| |
2416 __ b(eq, &done); | |
2417 __ ldr(feedback_map, FieldMemOperand(r4, 0)); | |
Erik Corry
2015/04/02 12:54:11
HeapObject::kMapOffset would be better than 0
| |
2418 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | |
2419 __ b(ne, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); | |
2420 | |
2421 // If r1 is not equal to the weak cell value, and the weak cell value is | |
Erik Corry
2015/04/02 12:54:11
Comment clarification suggestion:
r1 -> function
| |
2422 // cleared, we have a new chance to become monomorphic. | |
2423 __ JumpIfSmi(weak_value, &initialize); | |
2424 __ jmp(&megamorphic); | |
2393 | 2425 |
2394 if (!FLAG_pretenuring_call_new) { | 2426 if (!FLAG_pretenuring_call_new) { |
2427 __ bind(&check_allocation_site); | |
2395 // If we came here, we need to see if we are the array function. | 2428 // If we came here, we need to see if we are the array function. |
2396 // If we didn't have a matching function, and we didn't find the megamorph | 2429 // If we didn't have a matching function, and we didn't find the megamorph |
2397 // sentinel, then we have in the slot either some other function or an | 2430 // sentinel, then we have in the slot either some other function or an |
2398 // AllocationSite. Do a map check on the object in ecx. | 2431 // AllocationSite. Do a map check on the object in ecx. |
Erik Corry
2015/04/02 12:54:11
ecx? :-)
| |
2399 __ ldr(r5, FieldMemOperand(r4, 0)); | 2432 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); |
2400 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | |
2401 __ b(ne, &miss); | 2433 __ b(ne, &miss); |
2402 | 2434 |
2403 // Make sure the function is the Array() function | 2435 // Make sure the function is the Array() function |
2404 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 2436 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
2405 __ cmp(r1, r4); | 2437 __ cmp(r1, r4); |
2406 __ b(ne, &megamorphic); | 2438 __ b(ne, &megamorphic); |
2407 __ jmp(&done); | 2439 __ jmp(&done); |
2408 } | 2440 } |
2409 | 2441 |
2410 __ bind(&miss); | 2442 __ bind(&miss); |
(...skipping 15 matching lines...) Expand all Loading... | |
2426 | 2458 |
2427 if (!FLAG_pretenuring_call_new) { | 2459 if (!FLAG_pretenuring_call_new) { |
2428 // Make sure the function is the Array() function | 2460 // Make sure the function is the Array() function |
2429 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 2461 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
2430 __ cmp(r1, r4); | 2462 __ cmp(r1, r4); |
2431 __ b(ne, ¬_array_function); | 2463 __ b(ne, ¬_array_function); |
2432 | 2464 |
2433 // The target function is the Array constructor, | 2465 // The target function is the Array constructor, |
2434 // Create an AllocationSite if we don't already have it, store it in the | 2466 // Create an AllocationSite if we don't already have it, store it in the |
2435 // slot. | 2467 // slot. |
2436 { | 2468 CreateAllocationSiteStub create_stub(masm->isolate()); |
2437 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2469 CallStubInRecordCallTarget(masm, &create_stub); |
2438 | |
2439 // Arguments register must be smi-tagged to call out. | |
2440 __ SmiTag(r0); | |
2441 __ Push(r3, r2, r1, r0); | |
2442 | |
2443 CreateAllocationSiteStub create_stub(masm->isolate()); | |
2444 __ CallStub(&create_stub); | |
2445 | |
2446 __ Pop(r3, r2, r1, r0); | |
2447 __ SmiUntag(r0); | |
2448 } | |
2449 __ b(&done); | 2470 __ b(&done); |
2450 | 2471 |
2451 __ bind(¬_array_function); | 2472 __ bind(¬_array_function); |
2452 } | 2473 } |
2453 | 2474 |
2454 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2475 CreateWeakCellStub create_stub(masm->isolate()); |
2455 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 2476 CallStubInRecordCallTarget(masm, &create_stub); |
2456 __ str(r1, MemOperand(r4, 0)); | |
2457 | |
2458 __ Push(r4, r2, r1); | |
2459 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, | |
2460 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
2461 __ Pop(r4, r2, r1); | |
2462 | |
2463 __ bind(&done); | 2477 __ bind(&done); |
2464 } | 2478 } |
2465 | 2479 |
2466 | 2480 |
2467 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2481 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2468 // Do not transform the receiver for strict mode functions. | 2482 // Do not transform the receiver for strict mode functions. |
2469 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 2483 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
2470 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); | 2484 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); |
2471 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + | 2485 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + |
2472 kSmiTagSize))); | 2486 kSmiTagSize))); |
(...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5284 kStackUnwindSpace, NULL, | 5298 kStackUnwindSpace, NULL, |
5285 MemOperand(fp, 6 * kPointerSize), NULL); | 5299 MemOperand(fp, 6 * kPointerSize), NULL); |
5286 } | 5300 } |
5287 | 5301 |
5288 | 5302 |
5289 #undef __ | 5303 #undef __ |
5290 | 5304 |
5291 } } // namespace v8::internal | 5305 } } // namespace v8::internal |
5292 | 5306 |
5293 #endif // V8_TARGET_ARCH_ARM | 5307 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |