Commit f19fb455 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

MIPS: Minor fixes to simulator and builtins-mips.

Updated to include fixes to several mips arch-specific files, corresponding to recent changes in r7944, r7935, r7926, r7914, r7910, r7895, and parts of r7423, which had previously been missed for mips. Rebased on r7964.

The simulator changes were missed on r7893 for code-stubs-mips,
where the DirectCEntry stuff was added.

There are also a couple small changes to builtins-mips following
r7879 for the other architectures.

BUG=
TEST=

Review URL: http://codereview.chromium.org//7042031

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7977 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8ea947e6
...@@ -1202,13 +1202,10 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1202,13 +1202,10 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
kSmiTagSize))); kSmiTagSize)));
__ Branch(&shift_arguments, ne, t0, Operand(zero_reg)); __ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
// Do not transform the receiver for native (shared already in r2). // Do not transform the receiver for native (Compilerhints already in a3).
__ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kScriptOffset)); __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kES5Native +
__ LoadRoot(a3, Heap::kUndefinedValueRootIndex); kSmiTagSize)));
__ Branch(&shift_arguments, eq, a2, Operand(a3)); __ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
__ lw(a2, FieldMemOperand(a2, Script::kTypeOffset));
__ sra(a2, a2, kSmiTagSize);
__ Branch(&shift_arguments, eq, a2, Operand(Script::TYPE_NATIVE));
// Compute the receiver in non-strict mode. // Compute the receiver in non-strict mode.
// Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2). // Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2).
...@@ -1220,7 +1217,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1220,7 +1217,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// a2: first argument // a2: first argument
__ JumpIfSmi(a2, &convert_to_object, t2); __ JumpIfSmi(a2, &convert_to_object, t2);
// Heap::kUndefinedValueRootIndex is already in a3. __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
__ Branch(&use_global_receiver, eq, a2, Operand(a3)); __ Branch(&use_global_receiver, eq, a2, Operand(a3));
__ LoadRoot(a3, Heap::kNullValueRootIndex); __ LoadRoot(a3, Heap::kNullValueRootIndex);
__ Branch(&use_global_receiver, eq, a2, Operand(a3)); __ Branch(&use_global_receiver, eq, a2, Operand(a3));
...@@ -1389,20 +1386,17 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { ...@@ -1389,20 +1386,17 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
kSmiTagSize))); kSmiTagSize)));
__ Branch(&push_receiver, ne, t0, Operand(zero_reg)); __ Branch(&push_receiver, ne, t0, Operand(zero_reg));
// Do not transform the receiver for native (shared already in a1). // Do not transform the receiver for native (Compilerhints already in a2).
__ lw(a1, FieldMemOperand(a1, SharedFunctionInfo::kScriptOffset)); __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kES5Native +
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex); kSmiTagSize)));
__ Branch(&push_receiver, eq, a1, Operand(a2)); __ Branch(&push_receiver, ne, t0, Operand(zero_reg));
__ lw(a1, FieldMemOperand(a1, Script::kTypeOffset));
__ sra(a1, a1, kSmiTagSize);
__ Branch(&push_receiver, eq, a1, Operand(Script::TYPE_NATIVE));
// Compute the receiver in non-strict mode. // Compute the receiver in non-strict mode.
__ And(t0, a0, Operand(kSmiTagMask)); __ And(t0, a0, Operand(kSmiTagMask));
__ Branch(&call_to_object, eq, t0, Operand(zero_reg)); __ Branch(&call_to_object, eq, t0, Operand(zero_reg));
__ LoadRoot(a1, Heap::kNullValueRootIndex); __ LoadRoot(a1, Heap::kNullValueRootIndex);
__ Branch(&use_global_receiver, eq, a0, Operand(a1)); __ Branch(&use_global_receiver, eq, a0, Operand(a1));
// Heap::kUndefinedValueRootIndex is already in a2. __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
__ Branch(&use_global_receiver, eq, a0, Operand(a2)); __ Branch(&use_global_receiver, eq, a0, Operand(a2));
// Check if the receiver is already a JavaScript object. // Check if the receiver is already a JavaScript object.
......
...@@ -1472,7 +1472,7 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, ...@@ -1472,7 +1472,7 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
scratch1, scratch1,
Heap::kHeapNumberMapRootIndex, Heap::kHeapNumberMapRootIndex,
not_found, not_found,
true); DONT_DO_SMI_CHECK);
STATIC_ASSERT(8 == kDoubleSize); STATIC_ASSERT(8 == kDoubleSize);
__ Addu(scratch1, __ Addu(scratch1,
...@@ -1736,12 +1736,33 @@ void CompareStub::Generate(MacroAssembler* masm) { ...@@ -1736,12 +1736,33 @@ void CompareStub::Generate(MacroAssembler* masm) {
// The stub returns zero for false, and a non-zero value for true. // The stub returns zero for false, and a non-zero value for true.
void ToBooleanStub::Generate(MacroAssembler* masm) { void ToBooleanStub::Generate(MacroAssembler* masm) {
// This stub uses FPU instructions. // This stub uses FPU instructions.
ASSERT(CpuFeatures::IsEnabled(FPU)); CpuFeatures::Scope scope(FPU);
Label false_result; Label false_result;
Label not_heap_number; Label not_heap_number;
Register scratch0 = t5.is(tos_) ? t3 : t5; Register scratch0 = t5.is(tos_) ? t3 : t5;
// undefined -> false
__ LoadRoot(scratch0, Heap::kUndefinedValueRootIndex);
__ Branch(&false_result, eq, tos_, Operand(scratch0));
// Boolean -> its value
__ LoadRoot(scratch0, Heap::kFalseValueRootIndex);
__ Branch(&false_result, eq, tos_, Operand(scratch0));
__ LoadRoot(scratch0, Heap::kTrueValueRootIndex);
// "tos_" is a register and contains a non-zero value. Hence we implicitly
// return true if the equal condition is satisfied.
__ Ret(eq, tos_, Operand(scratch0));
// Smis: 0 -> false, all other -> true
__ And(scratch0, tos_, tos_);
__ Branch(&false_result, eq, scratch0, Operand(zero_reg));
__ And(scratch0, tos_, Operand(kSmiTagMask));
// "tos_" is a register and contains a non-zero value. Hence we implicitly
// return true if the not equal condition is satisfied.
__ Ret(eq, scratch0, Operand(zero_reg));
// 'null' -> false
__ LoadRoot(scratch0, Heap::kNullValueRootIndex); __ LoadRoot(scratch0, Heap::kNullValueRootIndex);
__ Branch(&false_result, eq, tos_, Operand(scratch0)); __ Branch(&false_result, eq, tos_, Operand(scratch0));
...@@ -1750,8 +1771,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { ...@@ -1750,8 +1771,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex); __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
__ Branch(&not_heap_number, ne, scratch0, Operand(at)); __ Branch(&not_heap_number, ne, scratch0, Operand(at));
__ Subu(at, tos_, Operand(kHeapObjectTag)); __ ldc1(f12, FieldMemOperand(tos_, HeapNumber::kValueOffset));
__ ldc1(f12, MemOperand(at, HeapNumber::kValueOffset));
__ fcmp(f12, 0.0, UEQ); __ fcmp(f12, 0.0, UEQ);
// "tos_" is a register, and contains a non zero value by default. // "tos_" is a register, and contains a non zero value by default.
...@@ -1762,11 +1782,6 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { ...@@ -1762,11 +1782,6 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
__ bind(&not_heap_number); __ bind(&not_heap_number);
// Check if the value is 'null'.
// 'null' => false.
__ LoadRoot(at, Heap::kNullValueRootIndex);
__ Branch(&false_result, eq, tos_, Operand(at));
// It can be an undetectable object. // It can be an undetectable object.
// Undetectable => false. // Undetectable => false.
__ lw(at, FieldMemOperand(tos_, HeapObject::kMapOffset)); __ lw(at, FieldMemOperand(tos_, HeapObject::kMapOffset));
...@@ -1944,12 +1959,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { ...@@ -1944,12 +1959,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow; Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &slow); GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
__ bind(&non_smi); __ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow); GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&slow); __ bind(&slow);
GenerateTypeTransition(masm); GenerateTypeTransition(masm);
__ bind(&call_builtin);
GenerateGenericCodeFallback(masm);
} }
...@@ -3185,7 +3202,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { ...@@ -3185,7 +3202,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
a1, a1,
Heap::kHeapNumberMapRootIndex, Heap::kHeapNumberMapRootIndex,
&calculate, &calculate,
true); DONT_DO_SMI_CHECK);
// Input is a HeapNumber. Store the // Input is a HeapNumber. Store the
// low and high words into a2, a3. // low and high words into a2, a3.
__ lw(a2, FieldMemOperand(a0, HeapNumber::kValueOffset)); __ lw(a2, FieldMemOperand(a0, HeapNumber::kValueOffset));
...@@ -3764,16 +3781,21 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { ...@@ -3764,16 +3781,21 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
#ifdef ENABLE_LOGGING_AND_PROFILING #ifdef ENABLE_LOGGING_AND_PROFILING
// If this is the outermost JS call, set js_entry_sp value. // If this is the outermost JS call, set js_entry_sp value.
Label non_outermost_js;
ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
masm->isolate()); masm->isolate());
__ li(t1, Operand(ExternalReference(js_entry_sp))); __ li(t1, Operand(ExternalReference(js_entry_sp)));
__ lw(t2, MemOperand(t1)); __ lw(t2, MemOperand(t1));
{ __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
Label skip; __ sw(fp, MemOperand(t1));
__ Branch(&skip, ne, t2, Operand(zero_reg)); __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
__ sw(fp, MemOperand(t1)); Label cont;
__ bind(&skip); __ b(&cont);
} __ nop(); // Branch delay slot nop.
__ bind(&non_outermost_js);
__ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
__ bind(&cont);
__ push(t0);
#endif #endif
// Call a faked try-block that does the invoke. // Call a faked try-block that does the invoke.
...@@ -3839,32 +3861,21 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { ...@@ -3839,32 +3861,21 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag); __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
__ Call(t9); __ Call(t9);
// Unlink this frame from the handler chain. When reading the // Unlink this frame from the handler chain.
// address of the next handler, there is no need to use the address __ PopTryHandler();
// displacement since the current stack pointer (sp) points directly
// to the stack handler.
__ lw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
__ li(t0, Operand(ExternalReference(Isolate::k_handler_address,
masm->isolate())));
__ sw(t1, MemOperand(t0));
// This restores sp to its position before PushTryHandler. __ bind(&exit); // v0 holds result
__ addiu(sp, sp, StackHandlerConstants::kSize); #ifdef ENABLE_LOGGING_AND_PROFILING
// Check if the current stack frame is marked as the outermost JS frame.
#ifdef ENABLE_LOGGING_AND_PROFILING Label non_outermost_js_2;
// If current FP value is the same as js_entry_sp value, it means that __ pop(t1);
// the current function is the outermost. __ Branch(&non_outermost_js_2, ne, t1,
__ li(t1, Operand(ExternalReference(js_entry_sp))); Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
__ lw(t2, MemOperand(t1)); __ li(t1, Operand(ExternalReference(js_entry_sp)));
{
Label skip;
__ Branch(&skip, ne, fp, Operand(t2));
__ sw(zero_reg, MemOperand(t1)); __ sw(zero_reg, MemOperand(t1));
__ bind(&skip); __ bind(&non_outermost_js_2);
} #endif
#endif
__ bind(&exit); // v0 holds result.
// Restore the top frame descriptors from the stack. // Restore the top frame descriptors from the stack.
__ pop(t1); __ pop(t1);
__ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address, __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address,
...@@ -4846,7 +4857,7 @@ void StringCharCodeAtGenerator::GenerateSlow( ...@@ -4846,7 +4857,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
scratch_, scratch_,
Heap::kHeapNumberMapRootIndex, Heap::kHeapNumberMapRootIndex,
index_not_number_, index_not_number_,
true); DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm); call_helper.BeforeCall(masm);
// Consumed by runtime conversion function: // Consumed by runtime conversion function:
__ Push(object_, index_, index_); __ Push(object_, index_, index_);
......
...@@ -566,19 +566,6 @@ void FullCodeGenerator::DoTest(Label* if_true, ...@@ -566,19 +566,6 @@ void FullCodeGenerator::DoTest(Label* if_true,
Label* if_false, Label* if_false,
Label* fall_through) { Label* fall_through) {
if (CpuFeatures::IsSupported(FPU)) { if (CpuFeatures::IsSupported(FPU)) {
CpuFeatures::Scope scope(FPU);
// Emit the inlined tests assumed by the stub.
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ Branch(if_false, eq, result_register(), Operand(at));
__ LoadRoot(at, Heap::kTrueValueRootIndex);
__ Branch(if_true, eq, result_register(), Operand(at));
__ LoadRoot(at, Heap::kFalseValueRootIndex);
__ Branch(if_false, eq, result_register(), Operand(at));
STATIC_ASSERT(kSmiTag == 0);
__ Branch(if_false, eq, result_register(), Operand(zero_reg));
__ JumpIfSmi(result_register(), if_true);
// Call the ToBoolean stub for all other cases.
ToBooleanStub stub(result_register()); ToBooleanStub stub(result_register());
__ CallStub(&stub); __ CallStub(&stub);
__ mov(at, zero_reg); __ mov(at, zero_reg);
...@@ -589,8 +576,6 @@ void FullCodeGenerator::DoTest(Label* if_true, ...@@ -589,8 +576,6 @@ void FullCodeGenerator::DoTest(Label* if_true,
__ CallRuntime(Runtime::kToBool, 1); __ CallRuntime(Runtime::kToBool, 1);
__ LoadRoot(at, Heap::kFalseValueRootIndex); __ LoadRoot(at, Heap::kFalseValueRootIndex);
} }
// The stub returns nonzero for true.
Split(ne, v0, Operand(at), if_true, if_false, fall_through); Split(ne, v0, Operand(at), if_true, if_false, fall_through);
} }
......
...@@ -874,10 +874,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { ...@@ -874,10 +874,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
} }
Object* KeyedLoadIC_Miss(Arguments args); void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- ra : return address // -- ra : return address
// -- a0 : key // -- a0 : key
...@@ -889,8 +886,11 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { ...@@ -889,8 +886,11 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
__ Push(a1, a0); __ Push(a1, a0);
ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss), // Perform tail call to the entry.
isolate); ExternalReference ref = force_generic
? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric), isolate)
: ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
__ TailCallExternalReference(ref, 2, 1); __ TailCallExternalReference(ref, 2, 1);
} }
...@@ -1097,7 +1097,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { ...@@ -1097,7 +1097,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
char_at_generator.GenerateSlow(masm, call_helper); char_at_generator.GenerateSlow(masm, call_helper);
__ bind(&miss); __ bind(&miss);
GenerateMiss(masm); GenerateMiss(masm, false);
} }
...@@ -1263,11 +1263,30 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { ...@@ -1263,11 +1263,30 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1);
__ bind(&slow); __ bind(&slow);
GenerateMiss(masm); GenerateMiss(masm, false);
}
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a2, a1, a0);
ExternalReference ref = force_generic
? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
masm->isolate())
: ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
__ TailCallExternalReference(ref, 3, 1);
} }
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- a0 : value // -- a0 : value
// -- a1 : key // -- a1 : key
...@@ -1279,8 +1298,11 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { ...@@ -1279,8 +1298,11 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
// We can't use MultiPush as the order of the registers is important. // We can't use MultiPush as the order of the registers is important.
__ Push(a2, a1, a0); __ Push(a2, a1, a0);
ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss), // The slow case calls into the runtime to complete the store without causing
masm->isolate()); // an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
__ TailCallExternalReference(ref, 3, 1); __ TailCallExternalReference(ref, 3, 1);
} }
......
...@@ -2545,8 +2545,8 @@ void MacroAssembler::CheckMap(Register obj, ...@@ -2545,8 +2545,8 @@ void MacroAssembler::CheckMap(Register obj,
Register scratch, Register scratch,
Handle<Map> map, Handle<Map> map,
Label* fail, Label* fail,
bool is_heap_object) { SmiCheckType smi_check_type) {
if (!is_heap_object) { if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, fail); JumpIfSmi(obj, fail);
} }
lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
...@@ -2555,12 +2555,27 @@ void MacroAssembler::CheckMap(Register obj, ...@@ -2555,12 +2555,27 @@ void MacroAssembler::CheckMap(Register obj,
} }
void MacroAssembler::DispatchMap(Register obj,
Register scratch,
Handle<Map> map,
Handle<Code> success,
SmiCheckType smi_check_type) {
Label fail;
if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, &fail);
}
lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
Jump(success, RelocInfo::CODE_TARGET, eq, scratch, Operand(map));
bind(&fail);
}
void MacroAssembler::CheckMap(Register obj, void MacroAssembler::CheckMap(Register obj,
Register scratch, Register scratch,
Heap::RootListIndex index, Heap::RootListIndex index,
Label* fail, Label* fail,
bool is_heap_object) { SmiCheckType smi_check_type) {
if (!is_heap_object) { if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, fail); JumpIfSmi(obj, fail);
} }
lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
...@@ -2860,7 +2875,7 @@ MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, ...@@ -2860,7 +2875,7 @@ MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub,
{ MaybeObject* maybe_result = stub->TryGetCode(); { MaybeObject* maybe_result = stub->TryGetCode();
if (!maybe_result->ToObject(&result)) return maybe_result; if (!maybe_result->ToObject(&result)) return maybe_result;
} }
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2); Jump(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond, r1, r2);
return result; return result;
} }
...@@ -3410,7 +3425,7 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, ...@@ -3410,7 +3425,7 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
lw(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); lw(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
if (emit_debug_code()) { if (emit_debug_code()) {
Label ok, fail; Label ok, fail;
CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, false); CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK);
Branch(&ok); Branch(&ok);
bind(&fail); bind(&fail);
Abort("Global functions must have initial map"); Abort("Global functions must have initial map");
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "assembler.h" #include "assembler.h"
#include "mips/assembler-mips.h" #include "mips/assembler-mips.h"
#include "v8globals.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -710,13 +711,22 @@ DECLARE_NOTARGET_PROTOTYPE(Ret) ...@@ -710,13 +711,22 @@ DECLARE_NOTARGET_PROTOTYPE(Ret)
Register scratch, Register scratch,
Handle<Map> map, Handle<Map> map,
Label* fail, Label* fail,
bool is_heap_object); SmiCheckType smi_check_type);
void CheckMap(Register obj, void CheckMap(Register obj,
Register scratch, Register scratch,
Heap::RootListIndex index, Heap::RootListIndex index,
Label* fail, Label* fail,
bool is_heap_object); SmiCheckType smi_check_type);
// Check if the map of an object is equal to a specified map and branch to a
// specified target if equal. Skip the smi check if not required (object is
// known to be a heap object)
void DispatchMap(Register obj,
Register scratch,
Handle<Map> map,
Handle<Code> success,
SmiCheckType smi_check_type);
// Generates code for reporting that an illegal operation has // Generates code for reporting that an illegal operation has
// occurred. // occurred.
......
...@@ -1165,7 +1165,11 @@ typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, ...@@ -1165,7 +1165,11 @@ typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
// This signature supports direct call in to API function native callback // This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h). // (refer to InvocationCallback in v8.h).
typedef v8::Handle<v8::Value> (*SimulatorRuntimeApiCall)(int32_t arg0); typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
// This signature supports direct call to accessor getter callback.
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
int32_t arg1);
// Software interrupt instructions are used by the simulator to call into the // Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime. They are also used for debugging with simulator. // C-based V8 runtime. They are also used for debugging with simulator.
...@@ -1240,15 +1244,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1240,15 +1244,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
set_register(v0, gpreg_pair[0]); set_register(v0, gpreg_pair[0]);
set_register(v1, gpreg_pair[1]); set_register(v1, gpreg_pair[1]);
} else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
SimulatorRuntimeApiCall target = // See DirectCEntryStub::GenerateCall for explanation of register usage.
reinterpret_cast<SimulatorRuntimeApiCall>(external); SimulatorRuntimeDirectApiCall target =
reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
if (::v8::internal::FLAG_trace_sim) { if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function at %p args %08x\n", PrintF("Call to host function at %p args %08x\n",
FUNCTION_ADDR(target), FUNCTION_ADDR(target), arg1);
arg0); }
v8::Handle<v8::Value> result = target(arg1);
*(reinterpret_cast<int*>(arg0)) = (int32_t) *result;
set_register(v0, arg0);
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
// See DirectCEntryStub::GenerateCall for explanation of register usage.
SimulatorRuntimeDirectGetterCall target =
reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function at %p args %08x %08x\n",
FUNCTION_ADDR(target), arg1, arg2);
} }
v8::Handle<v8::Value> result = target(arg0); v8::Handle<v8::Value> result = target(arg1, arg2);
set_register(v0, (int32_t) *result); *(reinterpret_cast<int*>(arg0)) = (int32_t) *result;
set_register(v0, arg0);
} else { } else {
SimulatorRuntimeCall target = SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external); reinterpret_cast<SimulatorRuntimeCall>(external);
......
...@@ -50,7 +50,7 @@ namespace internal { ...@@ -50,7 +50,7 @@ namespace internal {
entry(p0, p1, p2, p3, p4) entry(p0, p1, p2, p3, p4)
typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*, typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*,
int*, Address, int, Isolate*); void*, int*, Address, int, Isolate*);
// Call the generated regexp code directly. The code at the entry address // Call the generated regexp code directly. The code at the entry address
...@@ -58,7 +58,8 @@ typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*, ...@@ -58,7 +58,8 @@ typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*,
// The fifth argument is a dummy that reserves the space used for // The fifth argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls. // the return address added by the ExitFrame in native calls.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \ #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
(FUNCTION_CAST<mips_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7)) (FUNCTION_CAST<mips_regexp_matcher>(entry)( \
p0, p1, p2, p3, NULL, p4, p5, p6, p7))
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address) reinterpret_cast<TryCatch*>(try_catch_address)
...@@ -361,7 +362,7 @@ class Simulator { ...@@ -361,7 +362,7 @@ class Simulator {
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \ #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
Simulator::current(Isolate::Current())->Call( \ Simulator::current(Isolate::Current())->Call( \
entry, 8, p0, p1, p2, p3, p4, p5, p6, p7) entry, 9, p0, p1, p2, p3, NULL, p4, p5, p6, p7)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
try_catch_address == NULL ? \ try_catch_address == NULL ? \
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment