Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 1244023002: [arm] Address TODO in CallConstructStub::Generate. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); 2379 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
2380 __ SmiUntag(r9); 2380 __ SmiUntag(r9);
2381 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); 2381 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
2382 __ jmp(&check_underlying); // Go to (4). 2382 __ jmp(&check_underlying); // Go to (4).
2383 #endif // V8_INTERPRETED_REGEXP 2383 #endif // V8_INTERPRETED_REGEXP
2384 } 2384 }
2385 2385
2386 2386
2387 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { 2387 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
2388 // r0 : number of arguments to the construct function 2388 // r0 : number of arguments to the construct function
2389 // r2 : Feedback vector 2389 // r1 : the function to call
2390 // r2 : feedback vector
2390 // r3 : slot in feedback vector (Smi) 2391 // r3 : slot in feedback vector (Smi)
2391 // r1 : the function to call 2392 // r4 : original constructor
2392 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 2393 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2393 2394
2394 // Number-of-arguments register must be smi-tagged to call out. 2395 // Number-of-arguments register must be smi-tagged to call out.
2395 __ SmiTag(r0); 2396 __ SmiTag(r0);
2396 __ Push(r3, r2, r1, r0); 2397 __ Push(r3, r2, r1, r0);
2398 __ Push(r4);
Michael Starzinger 2015/07/21 13:22:26 Please don't make me implement the Push() variant
jbramley 2015/07/21 13:28:02 It doesn't matter quite as much for ARM anyway, si
2397 2399
2398 __ CallStub(stub); 2400 __ CallStub(stub);
2399 2401
2402 __ Pop(r4);
2400 __ Pop(r3, r2, r1, r0); 2403 __ Pop(r3, r2, r1, r0);
2401 __ SmiUntag(r0); 2404 __ SmiUntag(r0);
2402 } 2405 }
2403 2406
2404 2407
2405 static void GenerateRecordCallTarget(MacroAssembler* masm) { 2408 static void GenerateRecordCallTarget(MacroAssembler* masm) {
2406 // Cache the called function in a feedback vector slot. Cache states 2409 // Cache the called function in a feedback vector slot. Cache states
2407 // are uninitialized, monomorphic (indicated by a JSFunction), and 2410 // are uninitialized, monomorphic (indicated by a JSFunction), and
2408 // megamorphic. 2411 // megamorphic.
2409 // r0 : number of arguments to the construct function 2412 // r0 : number of arguments to the construct function
2410 // r1 : the function to call 2413 // r1 : the function to call
2411 // r2 : Feedback vector 2414 // r2 : feedback vector
2412 // r3 : slot in feedback vector (Smi) 2415 // r3 : slot in feedback vector (Smi)
2416 // r4 : original constructor
2413 Label initialize, done, miss, megamorphic, not_array_function; 2417 Label initialize, done, miss, megamorphic, not_array_function;
2414 2418
2415 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), 2419 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
2416 masm->isolate()->heap()->megamorphic_symbol()); 2420 masm->isolate()->heap()->megamorphic_symbol());
2417 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), 2421 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()),
2418 masm->isolate()->heap()->uninitialized_symbol()); 2422 masm->isolate()->heap()->uninitialized_symbol());
2419 2423
2420 // Load the cache state into r4. 2424 // Load the cache state into r5.
2421 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 2425 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
2422 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); 2426 __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize));
2423 2427
2424 // A monomorphic cache hit or an already megamorphic state: invoke the 2428 // A monomorphic cache hit or an already megamorphic state: invoke the
2425 // function without changing the state. 2429 // function without changing the state.
2426 // We don't know if r4 is a WeakCell or a Symbol, but it's harmless to read at 2430 // We don't know if r5 is a WeakCell or a Symbol, but it's harmless to read at
2427 // this position in a symbol (see static asserts in type-feedback-vector.h). 2431 // this position in a symbol (see static asserts in type-feedback-vector.h).
2428 Label check_allocation_site; 2432 Label check_allocation_site;
2429 Register feedback_map = r5; 2433 Register feedback_map = r6;
2430 Register weak_value = r6; 2434 Register weak_value = r9;
2431 __ ldr(weak_value, FieldMemOperand(r4, WeakCell::kValueOffset)); 2435 __ ldr(weak_value, FieldMemOperand(r5, WeakCell::kValueOffset));
2432 __ cmp(r1, weak_value); 2436 __ cmp(r1, weak_value);
2433 __ b(eq, &done); 2437 __ b(eq, &done);
2434 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); 2438 __ CompareRoot(r5, Heap::kmegamorphic_symbolRootIndex);
2435 __ b(eq, &done); 2439 __ b(eq, &done);
2436 __ ldr(feedback_map, FieldMemOperand(r4, HeapObject::kMapOffset)); 2440 __ ldr(feedback_map, FieldMemOperand(r5, HeapObject::kMapOffset));
2437 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); 2441 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex);
2438 __ b(ne, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); 2442 __ b(ne, FLAG_pretenuring_call_new ? &miss : &check_allocation_site);
2439 2443
2440 // If the weak cell is cleared, we have a new chance to become monomorphic. 2444 // If the weak cell is cleared, we have a new chance to become monomorphic.
2441 __ JumpIfSmi(weak_value, &initialize); 2445 __ JumpIfSmi(weak_value, &initialize);
2442 __ jmp(&megamorphic); 2446 __ jmp(&megamorphic);
2443 2447
2444 if (!FLAG_pretenuring_call_new) { 2448 if (!FLAG_pretenuring_call_new) {
2445 __ bind(&check_allocation_site); 2449 __ bind(&check_allocation_site);
2446 // If we came here, we need to see if we are the array function. 2450 // If we came here, we need to see if we are the array function.
2447 // If we didn't have a matching function, and we didn't find the megamorph 2451 // If we didn't have a matching function, and we didn't find the megamorph
2448 // sentinel, then we have in the slot either some other function or an 2452 // sentinel, then we have in the slot either some other function or an
2449 // AllocationSite. 2453 // AllocationSite.
2450 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); 2454 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex);
2451 __ b(ne, &miss); 2455 __ b(ne, &miss);
2452 2456
2453 // Make sure the function is the Array() function 2457 // Make sure the function is the Array() function
2454 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); 2458 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5);
2455 __ cmp(r1, r4); 2459 __ cmp(r1, r5);
2456 __ b(ne, &megamorphic); 2460 __ b(ne, &megamorphic);
2457 __ jmp(&done); 2461 __ jmp(&done);
2458 } 2462 }
2459 2463
2460 __ bind(&miss); 2464 __ bind(&miss);
2461 2465
2462 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 2466 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
2463 // megamorphic. 2467 // megamorphic.
2464 __ CompareRoot(r4, Heap::kuninitialized_symbolRootIndex); 2468 __ CompareRoot(r5, Heap::kuninitialized_symbolRootIndex);
2465 __ b(eq, &initialize); 2469 __ b(eq, &initialize);
2466 // MegamorphicSentinel is an immortal immovable object (undefined) so no 2470 // MegamorphicSentinel is an immortal immovable object (undefined) so no
2467 // write-barrier is needed. 2471 // write-barrier is needed.
2468 __ bind(&megamorphic); 2472 __ bind(&megamorphic);
2469 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 2473 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
2470 __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex); 2474 __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
2471 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize)); 2475 __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
2472 __ jmp(&done); 2476 __ jmp(&done);
2473 2477
2474 // An uninitialized cache is patched with the function 2478 // An uninitialized cache is patched with the function
2475 __ bind(&initialize); 2479 __ bind(&initialize);
2476 2480
2477 if (!FLAG_pretenuring_call_new) { 2481 if (!FLAG_pretenuring_call_new) {
2478 // Make sure the function is the Array() function 2482 // Make sure the function is the Array() function
2479 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); 2483 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5);
2480 __ cmp(r1, r4); 2484 __ cmp(r1, r5);
2481 __ b(ne, &not_array_function); 2485 __ b(ne, &not_array_function);
2482 2486
2483 // The target function is the Array constructor, 2487 // The target function is the Array constructor,
2484 // Create an AllocationSite if we don't already have it, store it in the 2488 // Create an AllocationSite if we don't already have it, store it in the
2485 // slot. 2489 // slot.
2486 CreateAllocationSiteStub create_stub(masm->isolate()); 2490 CreateAllocationSiteStub create_stub(masm->isolate());
2487 CallStubInRecordCallTarget(masm, &create_stub); 2491 CallStubInRecordCallTarget(masm, &create_stub);
2488 __ b(&done); 2492 __ b(&done);
2489 2493
2490 __ bind(&not_array_function); 2494 __ bind(&not_array_function);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 // r4 : original constructor (for IsSuperConstructorCall) 2621 // r4 : original constructor (for IsSuperConstructorCall)
2618 Label slow, non_function_call; 2622 Label slow, non_function_call;
2619 2623
2620 // Check that the function is not a smi. 2624 // Check that the function is not a smi.
2621 __ JumpIfSmi(r1, &non_function_call); 2625 __ JumpIfSmi(r1, &non_function_call);
2622 // Check that the function is a JSFunction. 2626 // Check that the function is a JSFunction.
2623 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); 2627 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE);
2624 __ b(ne, &slow); 2628 __ b(ne, &slow);
2625 2629
2626 if (RecordCallTarget()) { 2630 if (RecordCallTarget()) {
2627 if (IsSuperConstructorCall()) {
2628 __ push(r4);
2629 }
2630 // TODO(mstarzinger): Consider tweaking target recording to avoid push/pop.
2631 GenerateRecordCallTarget(masm); 2631 GenerateRecordCallTarget(masm);
2632 if (IsSuperConstructorCall()) {
2633 __ pop(r4);
2634 }
2635 2632
2636 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); 2633 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
2637 if (FLAG_pretenuring_call_new) { 2634 if (FLAG_pretenuring_call_new) {
2638 // Put the AllocationSite from the feedback vector into r2. 2635 // Put the AllocationSite from the feedback vector into r2.
2639 // By adding kPointerSize we encode that we know the AllocationSite 2636 // By adding kPointerSize we encode that we know the AllocationSite
2640 // entry is at the feedback vector slot given by r3 + 1. 2637 // entry is at the feedback vector slot given by r3 + 1.
2641 __ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize + kPointerSize)); 2638 __ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize + kPointerSize));
2642 } else { 2639 } else {
2643 Label feedback_register_initialized; 2640 Label feedback_register_initialized;
2644 // Put the AllocationSite from the feedback vector into r2, or undefined. 2641 // Put the AllocationSite from the feedback vector into r2, or undefined.
(...skipping 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after
5376 MemOperand(fp, 6 * kPointerSize), NULL); 5373 MemOperand(fp, 6 * kPointerSize), NULL);
5377 } 5374 }
5378 5375
5379 5376
5380 #undef __ 5377 #undef __
5381 5378
5382 } // namespace internal 5379 } // namespace internal
5383 } // namespace v8 5380 } // namespace v8
5384 5381
5385 #endif // V8_TARGET_ARCH_ARM 5382 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698