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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
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 2371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2382 // (9) Sliced string. Replace subject with parent. Go to (4). | 2382 // (9) Sliced string. Replace subject with parent. Go to (4). |
2383 // Load offset into t0 and replace subject string with parent. | 2383 // Load offset into t0 and replace subject string with parent. |
2384 __ lw(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2384 __ lw(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
2385 __ sra(t0, t0, kSmiTagSize); | 2385 __ sra(t0, t0, kSmiTagSize); |
2386 __ lw(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2386 __ lw(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
2387 __ jmp(&check_underlying); // Go to (4). | 2387 __ jmp(&check_underlying); // Go to (4). |
2388 #endif // V8_INTERPRETED_REGEXP | 2388 #endif // V8_INTERPRETED_REGEXP |
2389 } | 2389 } |
2390 | 2390 |
2391 | 2391 |
2392 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 2392 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
2393 bool is_super) { | |
2394 // a0 : number of arguments to the construct function | 2393 // a0 : number of arguments to the construct function |
2395 // a2 : feedback vector | 2394 // a2 : feedback vector |
2396 // a3 : slot in feedback vector (Smi) | 2395 // a3 : slot in feedback vector (Smi) |
2397 // a1 : the function to call | 2396 // a1 : the function to call |
2398 // t0 : new target (for IsSuperConstructorCall) | |
2399 FrameScope scope(masm, StackFrame::INTERNAL); | 2397 FrameScope scope(masm, StackFrame::INTERNAL); |
2400 const RegList kSavedRegs = 1 << 4 | // a0 | 2398 const RegList kSavedRegs = 1 << 4 | // a0 |
2401 1 << 5 | // a1 | 2399 1 << 5 | // a1 |
2402 1 << 6 | // a2 | 2400 1 << 6 | // a2 |
2403 1 << 7 | // a3 | 2401 1 << 7; // a3 |
2404 BoolToInt(is_super) << 8; // t0 | |
2405 | 2402 |
2406 // Number-of-arguments register must be smi-tagged to call out. | 2403 // Number-of-arguments register must be smi-tagged to call out. |
2407 __ SmiTag(a0); | 2404 __ SmiTag(a0); |
2408 __ MultiPush(kSavedRegs); | 2405 __ MultiPush(kSavedRegs); |
2409 | 2406 |
2410 __ CallStub(stub); | 2407 __ CallStub(stub); |
2411 | 2408 |
2412 __ MultiPop(kSavedRegs); | 2409 __ MultiPop(kSavedRegs); |
2413 __ SmiUntag(a0); | 2410 __ SmiUntag(a0); |
2414 } | 2411 } |
2415 | 2412 |
2416 | 2413 |
2417 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { | 2414 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
2418 // Cache the called function in a feedback vector slot. Cache states | 2415 // Cache the called function in a feedback vector slot. Cache states |
2419 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2416 // are uninitialized, monomorphic (indicated by a JSFunction), and |
2420 // megamorphic. | 2417 // megamorphic. |
2421 // a0 : number of arguments to the construct function | 2418 // a0 : number of arguments to the construct function |
2422 // a1 : the function to call | 2419 // a1 : the function to call |
2423 // a2 : feedback vector | 2420 // a2 : feedback vector |
2424 // a3 : slot in feedback vector (Smi) | 2421 // a3 : slot in feedback vector (Smi) |
2425 // t0 : new target (for IsSuperConstructorCall) | |
2426 Label initialize, done, miss, megamorphic, not_array_function; | 2422 Label initialize, done, miss, megamorphic, not_array_function; |
2427 | 2423 |
2428 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2424 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2429 masm->isolate()->heap()->megamorphic_symbol()); | 2425 masm->isolate()->heap()->megamorphic_symbol()); |
2430 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2426 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2431 masm->isolate()->heap()->uninitialized_symbol()); | 2427 masm->isolate()->heap()->uninitialized_symbol()); |
2432 | 2428 |
2433 // Load the cache state into t2. | 2429 // Load the cache state into t2. |
2434 __ sll(t2, a3, kPointerSizeLog2 - kSmiTagSize); | 2430 __ sll(t2, a3, kPointerSizeLog2 - kSmiTagSize); |
2435 __ Addu(t2, a2, Operand(t2)); | 2431 __ Addu(t2, a2, Operand(t2)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2485 // An uninitialized cache is patched with the function. | 2481 // An uninitialized cache is patched with the function. |
2486 __ bind(&initialize); | 2482 __ bind(&initialize); |
2487 // Make sure the function is the Array() function. | 2483 // Make sure the function is the Array() function. |
2488 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t2); | 2484 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t2); |
2489 __ Branch(¬_array_function, ne, a1, Operand(t2)); | 2485 __ Branch(¬_array_function, ne, a1, Operand(t2)); |
2490 | 2486 |
2491 // The target function is the Array constructor, | 2487 // The target function is the Array constructor, |
2492 // 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 |
2493 // slot. | 2489 // slot. |
2494 CreateAllocationSiteStub create_stub(masm->isolate()); | 2490 CreateAllocationSiteStub create_stub(masm->isolate()); |
2495 CallStubInRecordCallTarget(masm, &create_stub, is_super); | 2491 CallStubInRecordCallTarget(masm, &create_stub); |
2496 __ Branch(&done); | 2492 __ Branch(&done); |
2497 | 2493 |
2498 __ bind(¬_array_function); | 2494 __ bind(¬_array_function); |
2499 CreateWeakCellStub weak_cell_stub(masm->isolate()); | 2495 CreateWeakCellStub weak_cell_stub(masm->isolate()); |
2500 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2496 CallStubInRecordCallTarget(masm, &weak_cell_stub); |
2501 __ bind(&done); | 2497 __ bind(&done); |
2502 } | 2498 } |
2503 | 2499 |
2504 | 2500 |
2505 void CallConstructStub::Generate(MacroAssembler* masm) { | 2501 void CallConstructStub::Generate(MacroAssembler* masm) { |
2506 // a0 : number of arguments | 2502 // a0 : number of arguments |
2507 // a1 : the function to call | 2503 // a1 : the function to call |
2508 // a2 : feedback vector | 2504 // a2 : feedback vector |
2509 // a3 : slot in feedback vector (Smi, for RecordCallTarget) | 2505 // a3 : slot in feedback vector (Smi, for RecordCallTarget) |
2510 // t0 : new target (for IsSuperConstructorCall) | |
2511 | 2506 |
2512 Label non_function; | 2507 Label non_function; |
2513 // Check that the function is not a smi. | 2508 // Check that the function is not a smi. |
2514 __ JumpIfSmi(a1, &non_function); | 2509 __ JumpIfSmi(a1, &non_function); |
2515 // Check that the function is a JSFunction. | 2510 // Check that the function is a JSFunction. |
2516 __ GetObjectType(a1, t1, t1); | 2511 __ GetObjectType(a1, t1, t1); |
2517 __ Branch(&non_function, ne, t1, Operand(JS_FUNCTION_TYPE)); | 2512 __ Branch(&non_function, ne, t1, Operand(JS_FUNCTION_TYPE)); |
2518 | 2513 |
2519 if (RecordCallTarget()) { | 2514 GenerateRecordCallTarget(masm); |
2520 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); | |
2521 | 2515 |
2522 __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize); | 2516 __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize); |
2523 __ Addu(t1, a2, at); | 2517 __ Addu(t1, a2, at); |
2524 Label feedback_register_initialized; | 2518 Label feedback_register_initialized; |
2525 // Put the AllocationSite from the feedback vector into a2, or undefined. | 2519 // Put the AllocationSite from the feedback vector into a2, or undefined. |
2526 __ lw(a2, FieldMemOperand(t1, FixedArray::kHeaderSize)); | 2520 __ lw(a2, FieldMemOperand(t1, FixedArray::kHeaderSize)); |
2527 __ lw(t1, FieldMemOperand(a2, AllocationSite::kMapOffset)); | 2521 __ lw(t1, FieldMemOperand(a2, AllocationSite::kMapOffset)); |
2528 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 2522 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
2529 __ Branch(&feedback_register_initialized, eq, t1, Operand(at)); | 2523 __ Branch(&feedback_register_initialized, eq, t1, Operand(at)); |
2530 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 2524 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
2531 __ bind(&feedback_register_initialized); | 2525 __ bind(&feedback_register_initialized); |
2532 | 2526 |
2533 __ AssertUndefinedOrAllocationSite(a2, t1); | 2527 __ AssertUndefinedOrAllocationSite(a2, t1); |
2534 } | |
2535 | 2528 |
2536 // Pass function as new target. | 2529 // Pass function as new target. |
2537 if (IsSuperConstructorCall()) { | 2530 __ mov(a3, a1); |
2538 __ mov(a3, t0); | |
2539 } else { | |
2540 __ mov(a3, a1); | |
2541 } | |
2542 | 2531 |
2543 // Tail call to the function-specific construct stub (still in the caller | 2532 // Tail call to the function-specific construct stub (still in the caller |
2544 // context at this point). | 2533 // context at this point). |
2545 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 2534 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
2546 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset)); | 2535 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset)); |
2547 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2536 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
2548 __ Jump(at); | 2537 __ Jump(at); |
2549 | 2538 |
2550 __ bind(&non_function); | 2539 __ bind(&non_function); |
2551 __ mov(a3, a1); | 2540 __ mov(a3, a1); |
(...skipping 3030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5582 MemOperand(fp, 6 * kPointerSize), NULL); | 5571 MemOperand(fp, 6 * kPointerSize), NULL); |
5583 } | 5572 } |
5584 | 5573 |
5585 | 5574 |
5586 #undef __ | 5575 #undef __ |
5587 | 5576 |
5588 } // namespace internal | 5577 } // namespace internal |
5589 } // namespace v8 | 5578 } // namespace v8 |
5590 | 5579 |
5591 #endif // V8_TARGET_ARCH_MIPS | 5580 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |