| 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 2377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { | 2393 bool is_super) { |
| 2394 // a0 : number of arguments to the construct function | 2394 // a0 : number of arguments to the construct function |
| 2395 // a2 : feedback vector | 2395 // a2 : feedback vector |
| 2396 // a3 : slot in feedback vector (Smi) | 2396 // a3 : slot in feedback vector (Smi) |
| 2397 // a1 : the function to call | 2397 // a1 : the function to call |
| 2398 // t0 : original constructor (for IsSuperConstructorCall) | 2398 // t0 : new target (for IsSuperConstructorCall) |
| 2399 FrameScope scope(masm, StackFrame::INTERNAL); | 2399 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2400 const RegList kSavedRegs = 1 << 4 | // a0 | 2400 const RegList kSavedRegs = 1 << 4 | // a0 |
| 2401 1 << 5 | // a1 | 2401 1 << 5 | // a1 |
| 2402 1 << 6 | // a2 | 2402 1 << 6 | // a2 |
| 2403 1 << 7 | // a3 | 2403 1 << 7 | // a3 |
| 2404 BoolToInt(is_super) << 8; // t0 | 2404 BoolToInt(is_super) << 8; // t0 |
| 2405 | 2405 |
| 2406 // Number-of-arguments register must be smi-tagged to call out. | 2406 // Number-of-arguments register must be smi-tagged to call out. |
| 2407 __ SmiTag(a0); | 2407 __ SmiTag(a0); |
| 2408 __ MultiPush(kSavedRegs); | 2408 __ MultiPush(kSavedRegs); |
| 2409 | 2409 |
| 2410 __ CallStub(stub); | 2410 __ CallStub(stub); |
| 2411 | 2411 |
| 2412 __ MultiPop(kSavedRegs); | 2412 __ MultiPop(kSavedRegs); |
| 2413 __ SmiUntag(a0); | 2413 __ SmiUntag(a0); |
| 2414 } | 2414 } |
| 2415 | 2415 |
| 2416 | 2416 |
| 2417 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { | 2417 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { |
| 2418 // Cache the called function in a feedback vector slot. Cache states | 2418 // Cache the called function in a feedback vector slot. Cache states |
| 2419 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2419 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 2420 // megamorphic. | 2420 // megamorphic. |
| 2421 // a0 : number of arguments to the construct function | 2421 // a0 : number of arguments to the construct function |
| 2422 // a1 : the function to call | 2422 // a1 : the function to call |
| 2423 // a2 : feedback vector | 2423 // a2 : feedback vector |
| 2424 // a3 : slot in feedback vector (Smi) | 2424 // a3 : slot in feedback vector (Smi) |
| 2425 // t0 : original constructor (for IsSuperConstructorCall) | 2425 // t0 : new target (for IsSuperConstructorCall) |
| 2426 Label initialize, done, miss, megamorphic, not_array_function; | 2426 Label initialize, done, miss, megamorphic, not_array_function; |
| 2427 | 2427 |
| 2428 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2428 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
| 2429 masm->isolate()->heap()->megamorphic_symbol()); | 2429 masm->isolate()->heap()->megamorphic_symbol()); |
| 2430 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2430 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
| 2431 masm->isolate()->heap()->uninitialized_symbol()); | 2431 masm->isolate()->heap()->uninitialized_symbol()); |
| 2432 | 2432 |
| 2433 // Load the cache state into t2. | 2433 // Load the cache state into t2. |
| 2434 __ sll(t2, a3, kPointerSizeLog2 - kSmiTagSize); | 2434 __ sll(t2, a3, kPointerSizeLog2 - kSmiTagSize); |
| 2435 __ Addu(t2, a2, Operand(t2)); | 2435 __ Addu(t2, a2, Operand(t2)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2500 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2500 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); |
| 2501 __ bind(&done); | 2501 __ bind(&done); |
| 2502 } | 2502 } |
| 2503 | 2503 |
| 2504 | 2504 |
| 2505 void CallConstructStub::Generate(MacroAssembler* masm) { | 2505 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 2506 // a0 : number of arguments | 2506 // a0 : number of arguments |
| 2507 // a1 : the function to call | 2507 // a1 : the function to call |
| 2508 // a2 : feedback vector | 2508 // a2 : feedback vector |
| 2509 // a3 : slot in feedback vector (Smi, for RecordCallTarget) | 2509 // a3 : slot in feedback vector (Smi, for RecordCallTarget) |
| 2510 // t0 : original constructor (for IsSuperConstructorCall) | 2510 // t0 : new target (for IsSuperConstructorCall) |
| 2511 | 2511 |
| 2512 Label non_function; | 2512 Label non_function; |
| 2513 // Check that the function is not a smi. | 2513 // Check that the function is not a smi. |
| 2514 __ JumpIfSmi(a1, &non_function); | 2514 __ JumpIfSmi(a1, &non_function); |
| 2515 // Check that the function is a JSFunction. | 2515 // Check that the function is a JSFunction. |
| 2516 __ GetObjectType(a1, t1, t1); | 2516 __ GetObjectType(a1, t1, t1); |
| 2517 __ Branch(&non_function, ne, t1, Operand(JS_FUNCTION_TYPE)); | 2517 __ Branch(&non_function, ne, t1, Operand(JS_FUNCTION_TYPE)); |
| 2518 | 2518 |
| 2519 if (RecordCallTarget()) { | 2519 if (RecordCallTarget()) { |
| 2520 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); | 2520 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); |
| 2521 | 2521 |
| 2522 __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize); | 2522 __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize); |
| 2523 __ Addu(t1, a2, at); | 2523 __ Addu(t1, a2, at); |
| 2524 Label feedback_register_initialized; | 2524 Label feedback_register_initialized; |
| 2525 // Put the AllocationSite from the feedback vector into a2, or undefined. | 2525 // Put the AllocationSite from the feedback vector into a2, or undefined. |
| 2526 __ lw(a2, FieldMemOperand(t1, FixedArray::kHeaderSize)); | 2526 __ lw(a2, FieldMemOperand(t1, FixedArray::kHeaderSize)); |
| 2527 __ lw(t1, FieldMemOperand(a2, AllocationSite::kMapOffset)); | 2527 __ lw(t1, FieldMemOperand(a2, AllocationSite::kMapOffset)); |
| 2528 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 2528 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
| 2529 __ Branch(&feedback_register_initialized, eq, t1, Operand(at)); | 2529 __ Branch(&feedback_register_initialized, eq, t1, Operand(at)); |
| 2530 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 2530 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
| 2531 __ bind(&feedback_register_initialized); | 2531 __ bind(&feedback_register_initialized); |
| 2532 | 2532 |
| 2533 __ AssertUndefinedOrAllocationSite(a2, t1); | 2533 __ AssertUndefinedOrAllocationSite(a2, t1); |
| 2534 } | 2534 } |
| 2535 | 2535 |
| 2536 // Pass function as original constructor. | 2536 // Pass function as new target. |
| 2537 if (IsSuperConstructorCall()) { | 2537 if (IsSuperConstructorCall()) { |
| 2538 __ mov(a3, t0); | 2538 __ mov(a3, t0); |
| 2539 } else { | 2539 } else { |
| 2540 __ mov(a3, a1); | 2540 __ mov(a3, a1); |
| 2541 } | 2541 } |
| 2542 | 2542 |
| 2543 // Tail call to the function-specific construct stub (still in the caller | 2543 // Tail call to the function-specific construct stub (still in the caller |
| 2544 // context at this point). | 2544 // context at this point). |
| 2545 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 2545 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 2546 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset)); | 2546 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset)); |
| (...skipping 3095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5642 MemOperand(fp, 6 * kPointerSize), NULL); | 5642 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5643 } | 5643 } |
| 5644 | 5644 |
| 5645 | 5645 |
| 5646 #undef __ | 5646 #undef __ |
| 5647 | 5647 |
| 5648 } // namespace internal | 5648 } // namespace internal |
| 5649 } // namespace v8 | 5649 } // namespace v8 |
| 5650 | 5650 |
| 5651 #endif // V8_TARGET_ARCH_MIPS | 5651 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |