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
This commit is contained in:
parent
636e10d065
commit
150814a4ad
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user