OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 24 matching lines...) Expand all Loading... |
35 #include "codegen.h" | 35 #include "codegen.h" |
36 #include "debug.h" | 36 #include "debug.h" |
37 #include "runtime.h" | 37 #include "runtime.h" |
38 | 38 |
39 namespace v8 { | 39 namespace v8 { |
40 namespace internal { | 40 namespace internal { |
41 | 41 |
42 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) | 42 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) |
43 : Assembler(arg_isolate, buffer, size), | 43 : Assembler(arg_isolate, buffer, size), |
44 generating_stub_(false), | 44 generating_stub_(false), |
45 allow_stub_calls_(true) { | 45 allow_stub_calls_(true), |
| 46 has_frame_(false) { |
46 if (isolate() != NULL) { | 47 if (isolate() != NULL) { |
47 code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), | 48 code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), |
48 isolate()); | 49 isolate()); |
49 } | 50 } |
50 } | 51 } |
51 | 52 |
52 | 53 |
53 void MacroAssembler::LoadRoot(Register destination, | 54 void MacroAssembler::LoadRoot(Register destination, |
54 Heap::RootListIndex index) { | 55 Heap::RootListIndex index) { |
55 lw(destination, MemOperand(s6, index << kPointerSizeLog2)); | 56 lw(destination, MemOperand(s6, index << kPointerSizeLog2)); |
(...skipping 2243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2299 | 2300 |
2300 void MacroAssembler::Push(Handle<Object> handle) { | 2301 void MacroAssembler::Push(Handle<Object> handle) { |
2301 li(at, Operand(handle)); | 2302 li(at, Operand(handle)); |
2302 push(at); | 2303 push(at); |
2303 } | 2304 } |
2304 | 2305 |
2305 | 2306 |
2306 #ifdef ENABLE_DEBUGGER_SUPPORT | 2307 #ifdef ENABLE_DEBUGGER_SUPPORT |
2307 | 2308 |
2308 void MacroAssembler::DebugBreak() { | 2309 void MacroAssembler::DebugBreak() { |
2309 ASSERT(allow_stub_calls()); | |
2310 mov(a0, zero_reg); | 2310 mov(a0, zero_reg); |
2311 li(a1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); | 2311 li(a1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
2312 CEntryStub ces(1); | 2312 CEntryStub ces(1); |
| 2313 ASSERT(AllowThisStubCall(&ces)); |
2313 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 2314 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
2314 } | 2315 } |
2315 | 2316 |
2316 #endif // ENABLE_DEBUGGER_SUPPORT | 2317 #endif // ENABLE_DEBUGGER_SUPPORT |
2317 | 2318 |
2318 | 2319 |
2319 // --------------------------------------------------------------------------- | 2320 // --------------------------------------------------------------------------- |
2320 // Exception handling. | 2321 // Exception handling. |
2321 | 2322 |
2322 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 2323 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3164 } | 3165 } |
3165 } | 3166 } |
3166 | 3167 |
3167 | 3168 |
3168 void MacroAssembler::InvokeCode(Register code, | 3169 void MacroAssembler::InvokeCode(Register code, |
3169 const ParameterCount& expected, | 3170 const ParameterCount& expected, |
3170 const ParameterCount& actual, | 3171 const ParameterCount& actual, |
3171 InvokeFlag flag, | 3172 InvokeFlag flag, |
3172 const CallWrapper& call_wrapper, | 3173 const CallWrapper& call_wrapper, |
3173 CallKind call_kind) { | 3174 CallKind call_kind) { |
| 3175 // You can't call a function without a valid frame. |
| 3176 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3177 |
3174 Label done; | 3178 Label done; |
3175 | 3179 |
3176 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag, | 3180 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag, |
3177 call_wrapper, call_kind); | 3181 call_wrapper, call_kind); |
3178 if (flag == CALL_FUNCTION) { | 3182 if (flag == CALL_FUNCTION) { |
3179 SetCallKind(t1, call_kind); | 3183 SetCallKind(t1, call_kind); |
3180 Call(code); | 3184 Call(code); |
3181 } else { | 3185 } else { |
3182 ASSERT(flag == JUMP_FUNCTION); | 3186 ASSERT(flag == JUMP_FUNCTION); |
3183 SetCallKind(t1, call_kind); | 3187 SetCallKind(t1, call_kind); |
3184 Jump(code); | 3188 Jump(code); |
3185 } | 3189 } |
3186 // Continue here if InvokePrologue does handle the invocation due to | 3190 // Continue here if InvokePrologue does handle the invocation due to |
3187 // mismatched parameter counts. | 3191 // mismatched parameter counts. |
3188 bind(&done); | 3192 bind(&done); |
3189 } | 3193 } |
3190 | 3194 |
3191 | 3195 |
3192 void MacroAssembler::InvokeCode(Handle<Code> code, | 3196 void MacroAssembler::InvokeCode(Handle<Code> code, |
3193 const ParameterCount& expected, | 3197 const ParameterCount& expected, |
3194 const ParameterCount& actual, | 3198 const ParameterCount& actual, |
3195 RelocInfo::Mode rmode, | 3199 RelocInfo::Mode rmode, |
3196 InvokeFlag flag, | 3200 InvokeFlag flag, |
3197 CallKind call_kind) { | 3201 CallKind call_kind) { |
| 3202 // You can't call a function without a valid frame. |
| 3203 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3204 |
3198 Label done; | 3205 Label done; |
3199 | 3206 |
3200 InvokePrologue(expected, actual, code, no_reg, &done, flag, | 3207 InvokePrologue(expected, actual, code, no_reg, &done, flag, |
3201 NullCallWrapper(), call_kind); | 3208 NullCallWrapper(), call_kind); |
3202 if (flag == CALL_FUNCTION) { | 3209 if (flag == CALL_FUNCTION) { |
3203 SetCallKind(t1, call_kind); | 3210 SetCallKind(t1, call_kind); |
3204 Call(code, rmode); | 3211 Call(code, rmode); |
3205 } else { | 3212 } else { |
3206 SetCallKind(t1, call_kind); | 3213 SetCallKind(t1, call_kind); |
3207 Jump(code, rmode); | 3214 Jump(code, rmode); |
3208 } | 3215 } |
3209 // Continue here if InvokePrologue does handle the invocation due to | 3216 // Continue here if InvokePrologue does handle the invocation due to |
3210 // mismatched parameter counts. | 3217 // mismatched parameter counts. |
3211 bind(&done); | 3218 bind(&done); |
3212 } | 3219 } |
3213 | 3220 |
3214 | 3221 |
3215 void MacroAssembler::InvokeFunction(Register function, | 3222 void MacroAssembler::InvokeFunction(Register function, |
3216 const ParameterCount& actual, | 3223 const ParameterCount& actual, |
3217 InvokeFlag flag, | 3224 InvokeFlag flag, |
3218 const CallWrapper& call_wrapper, | 3225 const CallWrapper& call_wrapper, |
3219 CallKind call_kind) { | 3226 CallKind call_kind) { |
| 3227 // You can't call a function without a valid frame. |
| 3228 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3229 |
3220 // Contract with called JS functions requires that function is passed in a1. | 3230 // Contract with called JS functions requires that function is passed in a1. |
3221 ASSERT(function.is(a1)); | 3231 ASSERT(function.is(a1)); |
3222 Register expected_reg = a2; | 3232 Register expected_reg = a2; |
3223 Register code_reg = a3; | 3233 Register code_reg = a3; |
3224 | 3234 |
3225 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 3235 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
3226 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3236 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3227 lw(expected_reg, | 3237 lw(expected_reg, |
3228 FieldMemOperand(code_reg, | 3238 FieldMemOperand(code_reg, |
3229 SharedFunctionInfo::kFormalParameterCountOffset)); | 3239 SharedFunctionInfo::kFormalParameterCountOffset)); |
3230 sra(expected_reg, expected_reg, kSmiTagSize); | 3240 sra(expected_reg, expected_reg, kSmiTagSize); |
3231 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3241 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3232 | 3242 |
3233 ParameterCount expected(expected_reg); | 3243 ParameterCount expected(expected_reg); |
3234 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); | 3244 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); |
3235 } | 3245 } |
3236 | 3246 |
3237 | 3247 |
3238 void MacroAssembler::InvokeFunction(JSFunction* function, | 3248 void MacroAssembler::InvokeFunction(JSFunction* function, |
3239 const ParameterCount& actual, | 3249 const ParameterCount& actual, |
3240 InvokeFlag flag, | 3250 InvokeFlag flag, |
3241 CallKind call_kind) { | 3251 CallKind call_kind) { |
| 3252 // You can't call a function without a valid frame. |
| 3253 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3254 |
3242 ASSERT(function->is_compiled()); | 3255 ASSERT(function->is_compiled()); |
3243 | 3256 |
3244 // Get the function and setup the context. | 3257 // Get the function and setup the context. |
3245 li(a1, Operand(Handle<JSFunction>(function))); | 3258 li(a1, Operand(Handle<JSFunction>(function))); |
3246 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3259 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3247 | 3260 |
3248 // Invoke the cached code. | 3261 // Invoke the cached code. |
3249 Handle<Code> code(function->code()); | 3262 Handle<Code> code(function->code()); |
3250 ParameterCount expected(function->shared()->formal_parameter_count()); | 3263 ParameterCount expected(function->shared()->formal_parameter_count()); |
3251 if (V8::UseCrankshaft()) { | 3264 if (V8::UseCrankshaft()) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3342 lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); | 3355 lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); |
3343 lbu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 3356 lbu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
3344 } | 3357 } |
3345 | 3358 |
3346 | 3359 |
3347 // ----------------------------------------------------------------------------- | 3360 // ----------------------------------------------------------------------------- |
3348 // Runtime calls. | 3361 // Runtime calls. |
3349 | 3362 |
3350 void MacroAssembler::CallStub(CodeStub* stub, Condition cond, | 3363 void MacroAssembler::CallStub(CodeStub* stub, Condition cond, |
3351 Register r1, const Operand& r2) { | 3364 Register r1, const Operand& r2) { |
3352 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. | 3365 ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. |
3353 Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2); | 3366 Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2); |
3354 } | 3367 } |
3355 | 3368 |
3356 | 3369 |
3357 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond, | 3370 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond, |
3358 Register r1, const Operand& r2) { | 3371 Register r1, const Operand& r2) { |
3359 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. | 3372 ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. |
3360 Object* result; | 3373 Object* result; |
3361 { MaybeObject* maybe_result = stub->TryGetCode(); | 3374 { MaybeObject* maybe_result = stub->TryGetCode(); |
3362 if (!maybe_result->ToObject(&result)) return maybe_result; | 3375 if (!maybe_result->ToObject(&result)) return maybe_result; |
3363 } | 3376 } |
3364 Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, | 3377 Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, |
3365 kNoASTId, cond, r1, r2); | 3378 kNoASTId, cond, r1, r2); |
3366 return result; | 3379 return result; |
3367 } | 3380 } |
3368 | 3381 |
3369 | 3382 |
3370 void MacroAssembler::TailCallStub(CodeStub* stub) { | 3383 void MacroAssembler::TailCallStub(CodeStub* stub) { |
3371 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. | 3384 ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_); |
3372 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); | 3385 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); |
3373 } | 3386 } |
3374 | 3387 |
3375 | 3388 |
3376 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, | 3389 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, |
3377 Condition cond, | 3390 Condition cond, |
3378 Register r1, | 3391 Register r1, |
3379 const Operand& r2) { | 3392 const Operand& r2) { |
3380 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs. | |
3381 Object* result; | 3393 Object* result; |
3382 { MaybeObject* maybe_result = stub->TryGetCode(); | 3394 { MaybeObject* maybe_result = stub->TryGetCode(); |
3383 if (!maybe_result->ToObject(&result)) return maybe_result; | 3395 if (!maybe_result->ToObject(&result)) return maybe_result; |
3384 } | 3396 } |
3385 Jump(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond, r1, r2); | 3397 Jump(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond, r1, r2); |
3386 return result; | 3398 return result; |
3387 } | 3399 } |
3388 | 3400 |
3389 | 3401 |
3390 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 3402 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3479 li(a0, Operand(ExternalReference::isolate_address())); | 3491 li(a0, Operand(ExternalReference::isolate_address())); |
3480 CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate()), | 3492 CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate()), |
3481 1); | 3493 1); |
3482 mov(v0, s0); | 3494 mov(v0, s0); |
3483 jmp(&leave_exit_frame); | 3495 jmp(&leave_exit_frame); |
3484 | 3496 |
3485 return result; | 3497 return result; |
3486 } | 3498 } |
3487 | 3499 |
3488 | 3500 |
| 3501 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { |
| 3502 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false; |
| 3503 return stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_; |
| 3504 } |
| 3505 |
| 3506 |
3489 void MacroAssembler::IllegalOperation(int num_arguments) { | 3507 void MacroAssembler::IllegalOperation(int num_arguments) { |
3490 if (num_arguments > 0) { | 3508 if (num_arguments > 0) { |
3491 addiu(sp, sp, num_arguments * kPointerSize); | 3509 addiu(sp, sp, num_arguments * kPointerSize); |
3492 } | 3510 } |
3493 LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3511 LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
3494 } | 3512 } |
3495 | 3513 |
3496 | 3514 |
3497 void MacroAssembler::IndexFromHash(Register hash, | 3515 void MacroAssembler::IndexFromHash(Register hash, |
3498 Register index) { | 3516 Register index) { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3715 const ExternalReference& builtin) { | 3733 const ExternalReference& builtin) { |
3716 li(a1, Operand(builtin)); | 3734 li(a1, Operand(builtin)); |
3717 CEntryStub stub(1); | 3735 CEntryStub stub(1); |
3718 return TryTailCallStub(&stub); | 3736 return TryTailCallStub(&stub); |
3719 } | 3737 } |
3720 | 3738 |
3721 | 3739 |
3722 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 3740 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
3723 InvokeFlag flag, | 3741 InvokeFlag flag, |
3724 const CallWrapper& call_wrapper) { | 3742 const CallWrapper& call_wrapper) { |
| 3743 // You can't call a builtin without a valid frame. |
| 3744 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
| 3745 |
3725 GetBuiltinEntry(t9, id); | 3746 GetBuiltinEntry(t9, id); |
3726 if (flag == CALL_FUNCTION) { | 3747 if (flag == CALL_FUNCTION) { |
3727 call_wrapper.BeforeCall(CallSize(t9)); | 3748 call_wrapper.BeforeCall(CallSize(t9)); |
3728 SetCallKind(t1, CALL_AS_METHOD); | 3749 SetCallKind(t1, CALL_AS_METHOD); |
3729 Call(t9); | 3750 Call(t9); |
3730 call_wrapper.AfterCall(); | 3751 call_wrapper.AfterCall(); |
3731 } else { | 3752 } else { |
3732 ASSERT(flag == JUMP_FUNCTION); | 3753 ASSERT(flag == JUMP_FUNCTION); |
3733 SetCallKind(t1, CALL_AS_METHOD); | 3754 SetCallKind(t1, CALL_AS_METHOD); |
3734 Jump(t9); | 3755 Jump(t9); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3847 // from the real pointer as a smi. | 3868 // from the real pointer as a smi. |
3848 intptr_t p1 = reinterpret_cast<intptr_t>(msg); | 3869 intptr_t p1 = reinterpret_cast<intptr_t>(msg); |
3849 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; | 3870 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; |
3850 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); | 3871 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); |
3851 #ifdef DEBUG | 3872 #ifdef DEBUG |
3852 if (msg != NULL) { | 3873 if (msg != NULL) { |
3853 RecordComment("Abort message: "); | 3874 RecordComment("Abort message: "); |
3854 RecordComment(msg); | 3875 RecordComment(msg); |
3855 } | 3876 } |
3856 #endif | 3877 #endif |
3857 // Disable stub call restrictions to always allow calls to abort. | |
3858 AllowStubCallsScope allow_scope(this, true); | |
3859 | 3878 |
3860 li(a0, Operand(p0)); | 3879 li(a0, Operand(p0)); |
3861 push(a0); | 3880 push(a0); |
3862 li(a0, Operand(Smi::FromInt(p1 - p0))); | 3881 li(a0, Operand(Smi::FromInt(p1 - p0))); |
3863 push(a0); | 3882 push(a0); |
3864 CallRuntime(Runtime::kAbort, 2); | 3883 // Disable stub call restrictions to always allow calls to abort. |
| 3884 if (!has_frame_) { |
| 3885 // We don't actually want to generate a pile of code for this, so just |
| 3886 // claim there is a stack frame, without generating one. |
| 3887 FrameScope scope(this, StackFrame::NONE); |
| 3888 CallRuntime(Runtime::kAbort, 2); |
| 3889 } else { |
| 3890 CallRuntime(Runtime::kAbort, 2); |
| 3891 } |
3865 // Will not return here. | 3892 // Will not return here. |
3866 if (is_trampoline_pool_blocked()) { | 3893 if (is_trampoline_pool_blocked()) { |
3867 // If the calling code cares about the exact number of | 3894 // If the calling code cares about the exact number of |
3868 // instructions generated, we insert padding here to keep the size | 3895 // instructions generated, we insert padding here to keep the size |
3869 // of the Abort macro constant. | 3896 // of the Abort macro constant. |
3870 // Currently in debug mode with debug_code enabled the number of | 3897 // Currently in debug mode with debug_code enabled the number of |
3871 // generated instructions is 14, so we use this as a maximum value. | 3898 // generated instructions is 14, so we use this as a maximum value. |
3872 static const int kExpectedAbortInstructions = 14; | 3899 static const int kExpectedAbortInstructions = 14; |
3873 int abort_instructions = InstructionsGeneratedSince(&abort_start); | 3900 int abort_instructions = InstructionsGeneratedSince(&abort_start); |
3874 ASSERT(abort_instructions <= kExpectedAbortInstructions); | 3901 ASSERT(abort_instructions <= kExpectedAbortInstructions); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4283 ExternalReference::the_hole_value_location(isolate()), | 4310 ExternalReference::the_hole_value_location(isolate()), |
4284 scratch, | 4311 scratch, |
4285 num_arguments); | 4312 num_arguments); |
4286 } | 4313 } |
4287 | 4314 |
4288 | 4315 |
4289 void MacroAssembler::CallCFunctionHelper(Register function, | 4316 void MacroAssembler::CallCFunctionHelper(Register function, |
4290 ExternalReference function_reference, | 4317 ExternalReference function_reference, |
4291 Register scratch, | 4318 Register scratch, |
4292 int num_arguments) { | 4319 int num_arguments) { |
| 4320 ASSERT(has_frame()); |
4293 // Make sure that the stack is aligned before calling a C function unless | 4321 // Make sure that the stack is aligned before calling a C function unless |
4294 // running in the simulator. The simulator has its own alignment check which | 4322 // running in the simulator. The simulator has its own alignment check which |
4295 // provides more information. | 4323 // provides more information. |
4296 // The argument stots are presumed to have been set up by | 4324 // The argument stots are presumed to have been set up by |
4297 // PrepareCallCFunction. The C function must be called via t9, for mips ABI. | 4325 // PrepareCallCFunction. The C function must be called via t9, for mips ABI. |
4298 | 4326 |
4299 #if defined(V8_HOST_ARCH_MIPS) | 4327 #if defined(V8_HOST_ARCH_MIPS) |
4300 if (emit_debug_code()) { | 4328 if (emit_debug_code()) { |
4301 int frame_alignment = OS::ActivationFrameAlignment(); | 4329 int frame_alignment = OS::ActivationFrameAlignment(); |
4302 int frame_alignment_mask = frame_alignment - 1; | 4330 int frame_alignment_mask = frame_alignment - 1; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4403 opcode == BGTZL); | 4431 opcode == BGTZL); |
4404 opcode = (cond == eq) ? BEQ : BNE; | 4432 opcode = (cond == eq) ? BEQ : BNE; |
4405 instr = (instr & ~kOpcodeMask) | opcode; | 4433 instr = (instr & ~kOpcodeMask) | opcode; |
4406 masm_.emit(instr); | 4434 masm_.emit(instr); |
4407 } | 4435 } |
4408 | 4436 |
4409 | 4437 |
4410 } } // namespace v8::internal | 4438 } } // namespace v8::internal |
4411 | 4439 |
4412 #endif // V8_TARGET_ARCH_MIPS | 4440 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |