| 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 void KeyedLoadFieldStub::InitializeInterfaceDescriptor( | 159 void KeyedLoadFieldStub::InitializeInterfaceDescriptor( |
| 160 Isolate* isolate, | 160 Isolate* isolate, |
| 161 CodeStubInterfaceDescriptor* descriptor) { | 161 CodeStubInterfaceDescriptor* descriptor) { |
| 162 static Register registers[] = { a1 }; | 162 static Register registers[] = { a1 }; |
| 163 descriptor->register_param_count_ = 1; | 163 descriptor->register_param_count_ = 1; |
| 164 descriptor->register_params_ = registers; | 164 descriptor->register_params_ = registers; |
| 165 descriptor->deoptimization_handler_ = NULL; | 165 descriptor->deoptimization_handler_ = NULL; |
| 166 } | 166 } |
| 167 | 167 |
| 168 | 168 |
| 169 void KeyedArrayCallStub::InitializeInterfaceDescriptor( | |
| 170 Isolate* isolate, | |
| 171 CodeStubInterfaceDescriptor* descriptor) { | |
| 172 static Register registers[] = { a2 }; | |
| 173 descriptor->register_param_count_ = 1; | |
| 174 descriptor->register_params_ = registers; | |
| 175 descriptor->continuation_type_ = TAIL_CALL_CONTINUATION; | |
| 176 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; | |
| 177 descriptor->deoptimization_handler_ = | |
| 178 FUNCTION_ADDR(KeyedCallIC_MissFromStubFailure); | |
| 179 } | |
| 180 | |
| 181 | |
| 182 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( | 169 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( |
| 183 Isolate* isolate, | 170 Isolate* isolate, |
| 184 CodeStubInterfaceDescriptor* descriptor) { | 171 CodeStubInterfaceDescriptor* descriptor) { |
| 185 static Register registers[] = { a2, a1, a0 }; | 172 static Register registers[] = { a2, a1, a0 }; |
| 186 descriptor->register_param_count_ = 3; | 173 descriptor->register_param_count_ = 3; |
| 187 descriptor->register_params_ = registers; | 174 descriptor->register_params_ = registers; |
| 188 descriptor->deoptimization_handler_ = | 175 descriptor->deoptimization_handler_ = |
| 189 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); | 176 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); |
| 190 } | 177 } |
| 191 | 178 |
| (...skipping 3048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3240 __ sw(a1, FieldMemOperand(a2, Cell::kValueOffset)); | 3227 __ sw(a1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 3241 // No need for a write barrier here - cells are rescanned. | 3228 // No need for a write barrier here - cells are rescanned. |
| 3242 | 3229 |
| 3243 __ bind(&done); | 3230 __ bind(&done); |
| 3244 } | 3231 } |
| 3245 | 3232 |
| 3246 | 3233 |
| 3247 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3234 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 3248 // a1 : the function to call | 3235 // a1 : the function to call |
| 3249 // a2 : cache cell for call target | 3236 // a2 : cache cell for call target |
| 3250 Label slow, non_function; | 3237 Label slow, non_function, wrap, cont; |
| 3251 | 3238 |
| 3252 // Check that the function is really a JavaScript function. | 3239 if (NeedsChecks()) { |
| 3253 // a1: pushed function (to be verified) | 3240 // Check that the function is really a JavaScript function. |
| 3254 __ JumpIfSmi(a1, &non_function); | 3241 // a1: pushed function (to be verified) |
| 3242 __ JumpIfSmi(a1, &non_function); |
| 3255 | 3243 |
| 3256 // Goto slow case if we do not have a function. | 3244 // Goto slow case if we do not have a function. |
| 3257 __ GetObjectType(a1, a3, a3); | 3245 __ GetObjectType(a1, a3, a3); |
| 3258 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); | 3246 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); |
| 3259 | 3247 |
| 3260 if (RecordCallTarget()) { | 3248 if (RecordCallTarget()) { |
| 3261 GenerateRecordCallTarget(masm); | 3249 GenerateRecordCallTarget(masm); |
| 3250 } |
| 3262 } | 3251 } |
| 3263 | 3252 |
| 3264 // Fast-case: Invoke the function now. | 3253 // Fast-case: Invoke the function now. |
| 3265 // a1: pushed function | 3254 // a1: pushed function |
| 3266 ParameterCount actual(argc_); | 3255 ParameterCount actual(argc_); |
| 3267 | 3256 |
| 3257 if (CallAsMethod()) { |
| 3258 if (NeedsChecks()) { |
| 3259 // Do not transform the receiver for strict mode functions and natives. |
| 3260 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 3261 __ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset)); |
| 3262 int32_t strict_mode_function_mask = |
| 3263 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize); |
| 3264 int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize); |
| 3265 __ And(at, a3, Operand(strict_mode_function_mask | native_mask)); |
| 3266 __ Branch(&cont, ne, at, Operand(zero_reg)); |
| 3267 } |
| 3268 |
| 3269 // Compute the receiver in non-strict mode. |
| 3270 __ lw(a2, MemOperand(sp, argc_ * kPointerSize)); |
| 3271 |
| 3272 if (NeedsChecks()) { |
| 3273 // a0: actual number of arguments |
| 3274 // a1: function |
| 3275 // a2: first argument |
| 3276 __ JumpIfSmi(a2, &wrap); |
| 3277 __ GetObjectType(a2, a3, a3); |
| 3278 __ Branch(&wrap, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 3279 } else { |
| 3280 __ jmp(&wrap); |
| 3281 } |
| 3282 |
| 3283 __ bind(&cont); |
| 3284 } |
| 3268 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); | 3285 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 3269 | 3286 |
| 3270 // Slow-case: Non-function called. | 3287 if (NeedsChecks()) { |
| 3271 __ bind(&slow); | 3288 // Slow-case: Non-function called. |
| 3272 if (RecordCallTarget()) { | 3289 __ bind(&slow); |
| 3273 // If there is a call target cache, mark it megamorphic in the | 3290 if (RecordCallTarget()) { |
| 3274 // non-function case. MegamorphicSentinel is an immortal immovable | 3291 // If there is a call target cache, mark it megamorphic in the |
| 3275 // object (undefined) so no write barrier is needed. | 3292 // non-function case. MegamorphicSentinel is an immortal immovable |
| 3276 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), | 3293 // object (undefined) so no write barrier is needed. |
| 3277 masm->isolate()->heap()->undefined_value()); | 3294 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), |
| 3278 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3295 masm->isolate()->heap()->undefined_value()); |
| 3279 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); | 3296 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 3280 } | 3297 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); |
| 3281 // Check for function proxy. | 3298 } |
| 3282 __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3299 // Check for function proxy. |
| 3283 __ push(a1); // Put proxy as additional argument. | 3300 __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 3284 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); | 3301 __ push(a1); // Put proxy as additional argument. |
| 3285 __ li(a2, Operand(0, RelocInfo::NONE32)); | 3302 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); |
| 3286 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); | 3303 __ li(a2, Operand(0, RelocInfo::NONE32)); |
| 3287 { | 3304 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); |
| 3288 Handle<Code> adaptor = | 3305 { |
| 3289 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3306 Handle<Code> adaptor = |
| 3290 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3307 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 3308 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
| 3309 } |
| 3310 |
| 3311 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
| 3312 // of the original receiver from the call site). |
| 3313 __ bind(&non_function); |
| 3314 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); |
| 3315 __ li(a0, Operand(argc_)); // Set up the number of arguments. |
| 3316 __ li(a2, Operand(0, RelocInfo::NONE32)); |
| 3317 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION); |
| 3318 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 3319 RelocInfo::CODE_TARGET); |
| 3291 } | 3320 } |
| 3292 | 3321 |
| 3293 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3322 if (CallAsMethod()) { |
| 3294 // of the original receiver from the call site). | 3323 __ bind(&wrap); |
| 3295 __ bind(&non_function); | 3324 // Wrap the receiver and patch it back onto the stack. |
| 3296 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); | 3325 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 3297 __ li(a0, Operand(argc_)); // Set up the number of arguments. | 3326 __ Push(a1, a2); |
| 3298 __ mov(a2, zero_reg); | 3327 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 3299 __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION); | 3328 __ pop(a1); |
| 3300 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3329 } |
| 3301 RelocInfo::CODE_TARGET); | 3330 __ mov(a0, v0); |
| 3331 __ sw(a0, MemOperand(sp, argc_ * kPointerSize)); |
| 3332 __ jmp(&cont); |
| 3333 } |
| 3302 } | 3334 } |
| 3303 | 3335 |
| 3304 | 3336 |
| 3305 void CallConstructStub::Generate(MacroAssembler* masm) { | 3337 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 3306 // a0 : number of arguments | 3338 // a0 : number of arguments |
| 3307 // a1 : the function to call | 3339 // a1 : the function to call |
| 3308 // a2 : cache cell for call target | 3340 // a2 : cache cell for call target |
| 3309 Label slow, non_function_call; | 3341 Label slow, non_function_call; |
| 3310 | 3342 |
| 3311 // Check that the function is not a smi. | 3343 // Check that the function is not a smi. |
| (...skipping 1875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5187 if (function_mode_ == JS_FUNCTION_STUB_MODE) { | 5219 if (function_mode_ == JS_FUNCTION_STUB_MODE) { |
| 5188 __ Addu(a1, a1, Operand(1)); | 5220 __ Addu(a1, a1, Operand(1)); |
| 5189 } | 5221 } |
| 5190 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 5222 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 5191 __ sll(a1, a1, kPointerSizeLog2); | 5223 __ sll(a1, a1, kPointerSizeLog2); |
| 5192 __ Ret(USE_DELAY_SLOT); | 5224 __ Ret(USE_DELAY_SLOT); |
| 5193 __ Addu(sp, sp, a1); | 5225 __ Addu(sp, sp, a1); |
| 5194 } | 5226 } |
| 5195 | 5227 |
| 5196 | 5228 |
| 5197 void StubFailureTailCallTrampolineStub::Generate(MacroAssembler* masm) { | |
| 5198 CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs); | |
| 5199 __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); | |
| 5200 __ mov(a1, v0); | |
| 5201 int parameter_count_offset = | |
| 5202 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; | |
| 5203 __ lw(a0, MemOperand(fp, parameter_count_offset)); | |
| 5204 // The parameter count above includes the receiver for the arguments passed to | |
| 5205 // the deoptimization handler. Subtract the receiver for the parameter count | |
| 5206 // for the call. | |
| 5207 __ Subu(a0, a0, 1); | |
| 5208 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | |
| 5209 ParameterCount argument_count(a0); | |
| 5210 __ InvokeFunction(a1, argument_count, JUMP_FUNCTION, NullCallWrapper()); | |
| 5211 } | |
| 5212 | |
| 5213 | |
| 5214 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 5229 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
| 5215 if (masm->isolate()->function_entry_hook() != NULL) { | 5230 if (masm->isolate()->function_entry_hook() != NULL) { |
| 5216 ProfileEntryHookStub stub; | 5231 ProfileEntryHookStub stub; |
| 5217 __ push(ra); | 5232 __ push(ra); |
| 5218 __ CallStub(&stub); | 5233 __ CallStub(&stub); |
| 5219 __ pop(ra); | 5234 __ pop(ra); |
| 5220 } | 5235 } |
| 5221 } | 5236 } |
| 5222 | 5237 |
| 5223 | 5238 |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5712 MemOperand(fp, 6 * kPointerSize), | 5727 MemOperand(fp, 6 * kPointerSize), |
| 5713 NULL); | 5728 NULL); |
| 5714 } | 5729 } |
| 5715 | 5730 |
| 5716 | 5731 |
| 5717 #undef __ | 5732 #undef __ |
| 5718 | 5733 |
| 5719 } } // namespace v8::internal | 5734 } } // namespace v8::internal |
| 5720 | 5735 |
| 5721 #endif // V8_TARGET_ARCH_MIPS | 5736 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |