MIPS: Port to x64 and ARM and some refactoring of ia32.

Port r10174 (a410586).

BUG=
TEST=
Review URL: http://codereview.chromium.org/8821024

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10211 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 636e10d0
......@@ -291,7 +291,22 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
if (op->IsRegister()) {
return ToRegister(op->index());
} else if (op->IsConstantOperand()) {
__ li(scratch, ToOperand(op));
LConstantOperand* const_op = LConstantOperand::cast(op);
Handle<Object> literal = chunk_->LookupLiteral(const_op);
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
ASSERT(literal->IsNumber());
__ li(scratch, Operand(static_cast<int32_t>(literal->Number())));
} else if (r.IsDouble()) {
Abort("EmitLoadRegister: Unsupported double immediate.");
} else {
ASSERT(r.IsTagged());
if (literal->IsSmi()) {
__ li(scratch, Operand(literal));
} else {
__ LoadHeapObject(scratch, Handle<HeapObject>::cast(literal));
}
}
return scratch;
} else if (op->IsStackSlot() || op->IsArgument()) {
__ lw(scratch, ToMemOperand(op));
......@@ -1162,8 +1177,13 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
ASSERT(instr->result()->IsRegister());
__ li(ToRegister(instr->result()), Operand(instr->value()));
Handle<Object> value = instr->value();
if (value->IsSmi()) {
__ li(ToRegister(instr->result()), Operand(value));
} else {
__ LoadHeapObject(ToRegister(instr->result()),
Handle<HeapObject>::cast(value));
}
}
......@@ -2039,7 +2059,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
// offset to the location of the map check.
Register temp = ToRegister(instr->TempAt(0));
ASSERT(temp.is(t0));
__ li(InstanceofStub::right(), Operand(instr->function()));
__ LoadHeapObject(InstanceofStub::right(), instr->function());
static const int kAdditionalDelta = 7;
int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
Label before_push_delta;
......@@ -2219,7 +2239,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
}
} else {
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
LoadHeapObject(result, Handle<HeapObject>::cast(function));
__ LoadHeapObject(result, function);
}
}
......@@ -2673,7 +2693,7 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
LoadHeapObject(result, instr->hydrogen()->closure());
__ LoadHeapObject(result, instr->hydrogen()->closure());
}
......@@ -2743,7 +2763,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
__ mov(a0, v0);
__ li(a1, Operand(instr->function()));
__ LoadHeapObject(a1, instr->function());
CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD);
}
......@@ -3180,7 +3200,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
__ li(a1, Operand(instr->target()));
__ LoadHeapObject(a1, instr->target());
CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
}
......@@ -4008,10 +4028,20 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
ASSERT(instr->InputAt(0)->IsRegister());
Register reg = ToRegister(instr->InputAt(0));
DeoptimizeIf(ne, instr->environment(), reg,
Operand(instr->hydrogen()->target()));
Register reg = ToRegister(instr->value());
Handle<JSFunction> target = instr->hydrogen()->target();
if (isolate()->heap()->InNewSpace(*target)) {
Register reg = ToRegister(instr->value());
Handle<JSGlobalPropertyCell> cell =
isolate()->factory()->NewJSGlobalPropertyCell(target);
__ li(at, Operand(Handle<Object>(cell)));
__ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset));
DeoptimizeIf(ne, instr->environment(), reg,
Operand(at));
} else {
DeoptimizeIf(ne, instr->environment(), reg,
Operand(target));
}
}
......@@ -4080,19 +4110,6 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
}
void LCodeGen::LoadHeapObject(Register result,
Handle<HeapObject> object) {
if (heap()->InNewSpace(*object)) {
Handle<JSGlobalPropertyCell> cell =
factory()->NewJSGlobalPropertyCell(object);
__ li(result, Operand(cell));
__ lw(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
} else {
__ li(result, Operand(object));
}
}
void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
Register temp1 = ToRegister(instr->TempAt(0));
Register temp2 = ToRegister(instr->TempAt(1));
......@@ -4101,7 +4118,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
Handle<JSObject> current_prototype = instr->prototype();
// Load prototype object.
LoadHeapObject(temp1, current_prototype);
__ LoadHeapObject(temp1, current_prototype);
// Check prototype maps up to the holder.
while (!current_prototype.is_identical_to(holder)) {
......@@ -4113,7 +4130,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
current_prototype =
Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
// Load next prototype object.
LoadHeapObject(temp1, current_prototype);
__ LoadHeapObject(temp1, current_prototype);
}
// Check the holder map.
......@@ -4134,7 +4151,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
// than the expected one. The check isn't necessary if the boilerplate has
// already been converted to FAST_ELEMENTS.
if (boilerplate_elements_kind != FAST_ELEMENTS) {
LoadHeapObject(a1, instr->hydrogen()->boilerplate_object());
__ LoadHeapObject(a1, instr->hydrogen()->boilerplate_object());
// Load map into a2.
__ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset));
// Load the map's "bit field 2".
......@@ -4209,10 +4226,10 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
__ Addu(a2, result, Operand(*offset));
__ sw(a2, FieldMemOperand(result, total_offset));
LoadHeapObject(source, value_object);
__ LoadHeapObject(source, value_object);
EmitDeepCopy(value_object, result, source, offset);
} else if (value->IsHeapObject()) {
LoadHeapObject(a2, Handle<HeapObject>::cast(value));
__ LoadHeapObject(a2, Handle<HeapObject>::cast(value));
__ sw(a2, FieldMemOperand(result, total_offset));
} else {
__ li(a2, Operand(value));
......@@ -4238,7 +4255,7 @@ void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
__ bind(&allocated);
int offset = 0;
LoadHeapObject(a1, instr->hydrogen()->boilerplate());
__ LoadHeapObject(a1, instr->hydrogen()->boilerplate());
EmitDeepCopy(instr->hydrogen()->boilerplate(), v0, a1, &offset);
ASSERT_EQ(size, offset);
}
......
......@@ -1793,6 +1793,8 @@ class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
inputs_[0] = value;
}
LOperand* value() { return InputAt(0); }
DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
};
......
......@@ -81,6 +81,19 @@ void MacroAssembler::StoreRoot(Register source,
}
void MacroAssembler::LoadHeapObject(Register result,
Handle<HeapObject> object) {
if (isolate()->heap()->InNewSpace(*object)) {
Handle<JSGlobalPropertyCell> cell =
isolate()->factory()->NewJSGlobalPropertyCell(object);
li(result, Operand(cell));
lw(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
} else {
li(result, Operand(object));
}
}
// Push and pop all registers that can hold pointers.
void MacroAssembler::PushSafepointRegisters() {
// Safepoints expect a block of kNumSafepointRegisters values on the
......@@ -3555,7 +3568,7 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
ASSERT(flag == JUMP_FUNCTION || has_frame());
// Get the function and setup the context.
li(a1, Operand(function));
LoadHeapObject(a1, function);
lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
ParameterCount expected(function->shared()->formal_parameter_count());
......
......@@ -262,6 +262,7 @@ class MacroAssembler: public Assembler {
Heap::RootListIndex index,
Condition cond, Register src1, const Operand& src2);
void LoadHeapObject(Register dst, Handle<HeapObject> object);
// ---------------------------------------------------------------------------
// GC Support
......
......@@ -574,7 +574,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
// -----------------------------------
// Get the function and setup the context.
Handle<JSFunction> function = optimization.constant_function();
__ li(t1, Operand(function));
__ LoadHeapObject(t1, function);
__ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
// Pass the additional arguments FastHandleApiCall expects.
......@@ -1115,7 +1115,7 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
Register scratch1,
Register scratch2,
Register scratch3,
Handle<Object> value,
Handle<JSFunction> value,
Handle<String> name,
Label* miss) {
// Check that the receiver isn't a smi.
......@@ -1127,7 +1127,7 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
scratch1, scratch2, scratch3, name, miss);
// Return the constant value.
__ li(v0, Operand(value));
__ LoadHeapObject(v0, value);
__ Ret();
}
......@@ -2701,7 +2701,7 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<Object> value,
Handle<JSFunction> value,
Handle<String> name) {
// ----------- S t a t e -------------
// -- a0 : receiver
......@@ -2839,7 +2839,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<Object> value) {
Handle<JSFunction> value) {
// ----------- S t a t e -------------
// -- ra : return address
// -- a0 : key
......
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