| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 Isolate* isolate, | 355 Isolate* isolate, |
| 356 CodeStubInterfaceDescriptor* descriptor) { | 356 CodeStubInterfaceDescriptor* descriptor) { |
| 357 static Register registers[] = { a1, a0 }; | 357 static Register registers[] = { a1, a0 }; |
| 358 descriptor->register_param_count_ = 2; | 358 descriptor->register_param_count_ = 2; |
| 359 descriptor->register_params_ = registers; | 359 descriptor->register_params_ = registers; |
| 360 descriptor->deoptimization_handler_ = | 360 descriptor->deoptimization_handler_ = |
| 361 Runtime::FunctionForId(Runtime::kStringAdd)->entry; | 361 Runtime::FunctionForId(Runtime::kStringAdd)->entry; |
| 362 } | 362 } |
| 363 | 363 |
| 364 | 364 |
| 365 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { |
| 366 { |
| 367 CallInterfaceDescriptor* descriptor = |
| 368 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); |
| 369 static Register registers[] = { a1, // JSFunction |
| 370 cp, // context |
| 371 a0, // actual number of arguments |
| 372 a2, // expected number of arguments |
| 373 }; |
| 374 static Representation representations[] = { |
| 375 Representation::Tagged(), // JSFunction |
| 376 Representation::Tagged(), // context |
| 377 Representation::Integer32(), // actual number of arguments |
| 378 Representation::Integer32(), // expected number of arguments |
| 379 }; |
| 380 descriptor->register_param_count_ = 4; |
| 381 descriptor->register_params_ = registers; |
| 382 descriptor->param_representations_ = representations; |
| 383 } |
| 384 { |
| 385 CallInterfaceDescriptor* descriptor = |
| 386 isolate->call_descriptor(Isolate::KeyedCall); |
| 387 static Register registers[] = { cp, // context |
| 388 a2, // key |
| 389 }; |
| 390 static Representation representations[] = { |
| 391 Representation::Tagged(), // context |
| 392 Representation::Tagged(), // key |
| 393 }; |
| 394 descriptor->register_param_count_ = 2; |
| 395 descriptor->register_params_ = registers; |
| 396 descriptor->param_representations_ = representations; |
| 397 } |
| 398 { |
| 399 CallInterfaceDescriptor* descriptor = |
| 400 isolate->call_descriptor(Isolate::NamedCall); |
| 401 static Register registers[] = { cp, // context |
| 402 a2, // name |
| 403 }; |
| 404 static Representation representations[] = { |
| 405 Representation::Tagged(), // context |
| 406 Representation::Tagged(), // name |
| 407 }; |
| 408 descriptor->register_param_count_ = 2; |
| 409 descriptor->register_params_ = registers; |
| 410 descriptor->param_representations_ = representations; |
| 411 } |
| 412 } |
| 413 |
| 414 |
| 365 #define __ ACCESS_MASM(masm) | 415 #define __ ACCESS_MASM(masm) |
| 366 | 416 |
| 367 | 417 |
| 368 static void EmitIdenticalObjectComparison(MacroAssembler* masm, | 418 static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
| 369 Label* slow, | 419 Label* slow, |
| 370 Condition cc); | 420 Condition cc); |
| 371 static void EmitSmiNonsmiComparison(MacroAssembler* masm, | 421 static void EmitSmiNonsmiComparison(MacroAssembler* masm, |
| 372 Register lhs, | 422 Register lhs, |
| 373 Register rhs, | 423 Register rhs, |
| 374 Label* rhs_not_nan, | 424 Label* rhs_not_nan, |
| (...skipping 2950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3325 | 3375 |
| 3326 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3376 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 3327 // a1 : the function to call | 3377 // a1 : the function to call |
| 3328 // a2 : cache cell for call target | 3378 // a2 : cache cell for call target |
| 3329 Label slow, non_function; | 3379 Label slow, non_function; |
| 3330 | 3380 |
| 3331 // Check that the function is really a JavaScript function. | 3381 // Check that the function is really a JavaScript function. |
| 3332 // a1: pushed function (to be verified) | 3382 // a1: pushed function (to be verified) |
| 3333 __ JumpIfSmi(a1, &non_function); | 3383 __ JumpIfSmi(a1, &non_function); |
| 3334 | 3384 |
| 3335 // The receiver might implicitly be the global object. This is | 3385 // Goto slow case if we do not have a function. |
| 3336 // indicated by passing the hole as the receiver to the call | 3386 __ GetObjectType(a1, a3, a3); |
| 3337 // function stub. | 3387 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); |
| 3338 if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) { | |
| 3339 Label try_call, call, patch_current_context; | |
| 3340 if (ReceiverMightBeImplicit()) { | |
| 3341 // Get the receiver from the stack. | |
| 3342 // function, receiver [, arguments] | |
| 3343 __ lw(t0, MemOperand(sp, argc_ * kPointerSize)); | |
| 3344 // Call as function is indicated with the hole. | |
| 3345 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
| 3346 __ Branch(&try_call, ne, t0, Operand(at)); | |
| 3347 } | |
| 3348 // Patch the receiver on the stack with the global receiver object. | |
| 3349 // Goto slow case if we do not have a function. | |
| 3350 __ GetObjectType(a1, a3, a3); | |
| 3351 __ Branch(&patch_current_context, ne, a3, Operand(JS_FUNCTION_TYPE)); | |
| 3352 CallStubCompiler::FetchGlobalProxy(masm, a3, a1); | |
| 3353 __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); | |
| 3354 __ Branch(&call); | |
| 3355 | |
| 3356 __ bind(&patch_current_context); | |
| 3357 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); | |
| 3358 __ sw(t0, MemOperand(sp, argc_ * kPointerSize)); | |
| 3359 __ Branch(&slow); | |
| 3360 | |
| 3361 __ bind(&try_call); | |
| 3362 // Get the map of the function object. | |
| 3363 __ GetObjectType(a1, a3, a3); | |
| 3364 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); | |
| 3365 | |
| 3366 __ bind(&call); | |
| 3367 } else { | |
| 3368 // Get the map of the function object. | |
| 3369 __ GetObjectType(a1, a3, a3); | |
| 3370 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); | |
| 3371 } | |
| 3372 | 3388 |
| 3373 if (RecordCallTarget()) { | 3389 if (RecordCallTarget()) { |
| 3374 GenerateRecordCallTarget(masm); | 3390 GenerateRecordCallTarget(masm); |
| 3375 } | 3391 } |
| 3376 | 3392 |
| 3377 // Fast-case: Invoke the function now. | 3393 // Fast-case: Invoke the function now. |
| 3378 // a1: pushed function | 3394 // a1: pushed function |
| 3379 ParameterCount actual(argc_); | 3395 ParameterCount actual(argc_); |
| 3380 | 3396 |
| 3381 if (ReceiverMightBeImplicit()) { | 3397 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 3382 Label call_as_function; | |
| 3383 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
| 3384 __ Branch(&call_as_function, eq, t0, Operand(at)); | |
| 3385 __ InvokeFunction(a1, | |
| 3386 actual, | |
| 3387 JUMP_FUNCTION, | |
| 3388 NullCallWrapper(), | |
| 3389 CALL_AS_METHOD); | |
| 3390 __ bind(&call_as_function); | |
| 3391 } | |
| 3392 __ InvokeFunction(a1, | |
| 3393 actual, | |
| 3394 JUMP_FUNCTION, | |
| 3395 NullCallWrapper(), | |
| 3396 CALL_AS_FUNCTION); | |
| 3397 | 3398 |
| 3398 // Slow-case: Non-function called. | 3399 // Slow-case: Non-function called. |
| 3399 __ bind(&slow); | 3400 __ bind(&slow); |
| 3400 if (RecordCallTarget()) { | 3401 if (RecordCallTarget()) { |
| 3401 // If there is a call target cache, mark it megamorphic in the | 3402 // If there is a call target cache, mark it megamorphic in the |
| 3402 // non-function case. MegamorphicSentinel is an immortal immovable | 3403 // non-function case. MegamorphicSentinel is an immortal immovable |
| 3403 // object (undefined) so no write barrier is needed. | 3404 // object (undefined) so no write barrier is needed. |
| 3404 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), | 3405 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), |
| 3405 masm->isolate()->heap()->undefined_value()); | 3406 masm->isolate()->heap()->undefined_value()); |
| 3406 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3407 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 3407 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); | 3408 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); |
| 3408 } | 3409 } |
| 3409 // Check for function proxy. | 3410 // Check for function proxy. |
| 3410 __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3411 __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 3411 __ push(a1); // Put proxy as additional argument. | 3412 __ push(a1); // Put proxy as additional argument. |
| 3412 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); | 3413 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); |
| 3413 __ li(a2, Operand(0, RelocInfo::NONE32)); | 3414 __ li(a2, Operand(0, RelocInfo::NONE32)); |
| 3414 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); | 3415 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); |
| 3415 __ SetCallKind(t1, CALL_AS_FUNCTION); | |
| 3416 { | 3416 { |
| 3417 Handle<Code> adaptor = | 3417 Handle<Code> adaptor = |
| 3418 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3418 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 3419 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3419 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
| 3420 } | 3420 } |
| 3421 | 3421 |
| 3422 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3422 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
| 3423 // of the original receiver from the call site). | 3423 // of the original receiver from the call site). |
| 3424 __ bind(&non_function); | 3424 __ bind(&non_function); |
| 3425 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); | 3425 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); |
| 3426 __ li(a0, Operand(argc_)); // Set up the number of arguments. | 3426 __ li(a0, Operand(argc_)); // Set up the number of arguments. |
| 3427 __ mov(a2, zero_reg); | 3427 __ mov(a2, zero_reg); |
| 3428 __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION); | 3428 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION); |
| 3429 __ SetCallKind(t1, CALL_AS_METHOD); | |
| 3430 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3429 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 3431 RelocInfo::CODE_TARGET); | 3430 RelocInfo::CODE_TARGET); |
| 3432 } | 3431 } |
| 3433 | 3432 |
| 3434 | 3433 |
| 3435 void CallConstructStub::Generate(MacroAssembler* masm) { | 3434 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 3436 // a0 : number of arguments | 3435 // a0 : number of arguments |
| 3437 // a1 : the function to call | 3436 // a1 : the function to call |
| 3438 // a2 : cache cell for call target | 3437 // a2 : cache cell for call target |
| 3439 Label slow, non_function_call; | 3438 Label slow, non_function_call; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3455 SharedFunctionInfo::kConstructStubOffset)); | 3454 SharedFunctionInfo::kConstructStubOffset)); |
| 3456 __ Addu(at, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3455 __ Addu(at, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 3457 __ Jump(at); | 3456 __ Jump(at); |
| 3458 | 3457 |
| 3459 // a0: number of arguments | 3458 // a0: number of arguments |
| 3460 // a1: called object | 3459 // a1: called object |
| 3461 // a3: object type | 3460 // a3: object type |
| 3462 Label do_call; | 3461 Label do_call; |
| 3463 __ bind(&slow); | 3462 __ bind(&slow); |
| 3464 __ Branch(&non_function_call, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3463 __ Branch(&non_function_call, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 3465 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); | 3464 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); |
| 3466 __ jmp(&do_call); | 3465 __ jmp(&do_call); |
| 3467 | 3466 |
| 3468 __ bind(&non_function_call); | 3467 __ bind(&non_function_call); |
| 3469 __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 3468 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
| 3470 __ bind(&do_call); | 3469 __ bind(&do_call); |
| 3471 // Set expected number of arguments to zero (not changing r0). | 3470 // Set expected number of arguments to zero (not changing r0). |
| 3472 __ li(a2, Operand(0, RelocInfo::NONE32)); | 3471 __ li(a2, Operand(0, RelocInfo::NONE32)); |
| 3473 __ SetCallKind(t1, CALL_AS_METHOD); | |
| 3474 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3472 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 3475 RelocInfo::CODE_TARGET); | 3473 RelocInfo::CODE_TARGET); |
| 3476 } | 3474 } |
| 3477 | 3475 |
| 3478 | 3476 |
| 3479 // StringCharCodeAtGenerator. | 3477 // StringCharCodeAtGenerator. |
| 3480 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 3478 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
| 3481 Label flat_string; | 3479 Label flat_string; |
| 3482 Label ascii_string; | 3480 Label ascii_string; |
| 3483 Label got_char_code; | 3481 Label got_char_code; |
| (...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5646 __ mov(a1, v0); | 5644 __ mov(a1, v0); |
| 5647 int parameter_count_offset = | 5645 int parameter_count_offset = |
| 5648 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; | 5646 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; |
| 5649 __ lw(a0, MemOperand(fp, parameter_count_offset)); | 5647 __ lw(a0, MemOperand(fp, parameter_count_offset)); |
| 5650 // The parameter count above includes the receiver for the arguments passed to | 5648 // The parameter count above includes the receiver for the arguments passed to |
| 5651 // the deoptimization handler. Subtract the receiver for the parameter count | 5649 // the deoptimization handler. Subtract the receiver for the parameter count |
| 5652 // for the call. | 5650 // for the call. |
| 5653 __ Subu(a0, a0, 1); | 5651 __ Subu(a0, a0, 1); |
| 5654 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 5652 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 5655 ParameterCount argument_count(a0); | 5653 ParameterCount argument_count(a0); |
| 5656 __ InvokeFunction( | 5654 __ InvokeFunction(a1, argument_count, JUMP_FUNCTION, NullCallWrapper()); |
| 5657 a1, argument_count, JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | |
| 5658 } | 5655 } |
| 5659 | 5656 |
| 5660 | 5657 |
| 5661 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 5658 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
| 5662 if (masm->isolate()->function_entry_hook() != NULL) { | 5659 if (masm->isolate()->function_entry_hook() != NULL) { |
| 5663 ProfileEntryHookStub stub; | 5660 ProfileEntryHookStub stub; |
| 5664 __ push(ra); | 5661 __ push(ra); |
| 5665 __ CallStub(&stub); | 5662 __ CallStub(&stub); |
| 5666 __ pop(ra); | 5663 __ pop(ra); |
| 5667 } | 5664 } |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6023 __ bind(&fast_elements_case); | 6020 __ bind(&fast_elements_case); |
| 6024 GenerateCase(masm, FAST_ELEMENTS); | 6021 GenerateCase(masm, FAST_ELEMENTS); |
| 6025 } | 6022 } |
| 6026 | 6023 |
| 6027 | 6024 |
| 6028 #undef __ | 6025 #undef __ |
| 6029 | 6026 |
| 6030 } } // namespace v8::internal | 6027 } } // namespace v8::internal |
| 6031 | 6028 |
| 6032 #endif // V8_TARGET_ARCH_MIPS | 6029 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |