MIPS: Replace LoadNamedFieldPolymorphic with explicit branches.
Port r16133 (dce32514) BUG= Review URL: https://codereview.chromium.org/22255005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16151 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c52b7bba05
commit
ba8b106059
@ -2921,90 +2921,6 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
|
|
||||||
Register object,
|
|
||||||
Handle<Map> type,
|
|
||||||
Handle<String> name,
|
|
||||||
LEnvironment* env) {
|
|
||||||
LookupResult lookup(isolate());
|
|
||||||
type->LookupDescriptor(NULL, *name, &lookup);
|
|
||||||
ASSERT(lookup.IsFound() || lookup.IsCacheable());
|
|
||||||
if (lookup.IsField()) {
|
|
||||||
int index = lookup.GetLocalFieldIndexFromMap(*type);
|
|
||||||
int offset = index * kPointerSize;
|
|
||||||
if (index < 0) {
|
|
||||||
// Negative property indices are in-object properties, indexed
|
|
||||||
// from the end of the fixed part of the object.
|
|
||||||
__ lw(result, FieldMemOperand(object, offset + type->instance_size()));
|
|
||||||
} else {
|
|
||||||
// Non-negative property indices are in the properties array.
|
|
||||||
__ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
|
|
||||||
__ lw(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
|
|
||||||
}
|
|
||||||
} else if (lookup.IsConstant()) {
|
|
||||||
Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
|
|
||||||
__ LoadObject(result, constant);
|
|
||||||
} else {
|
|
||||||
// Negative lookup.
|
|
||||||
// Check prototypes.
|
|
||||||
Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
|
|
||||||
Heap* heap = type->GetHeap();
|
|
||||||
while (*current != heap->null_value()) {
|
|
||||||
__ LoadHeapObject(result, current);
|
|
||||||
__ lw(result, FieldMemOperand(result, HeapObject::kMapOffset));
|
|
||||||
DeoptimizeIf(ne, env, result, Operand(Handle<Map>(current->map())));
|
|
||||||
current =
|
|
||||||
Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
|
|
||||||
}
|
|
||||||
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
|
|
||||||
Register object = ToRegister(instr->object());
|
|
||||||
Register result = ToRegister(instr->result());
|
|
||||||
Register object_map = scratch0();
|
|
||||||
|
|
||||||
int map_count = instr->hydrogen()->types()->length();
|
|
||||||
bool need_generic = instr->hydrogen()->need_generic();
|
|
||||||
|
|
||||||
if (map_count == 0 && !need_generic) {
|
|
||||||
DeoptimizeIf(al, instr->environment());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Handle<String> name = instr->hydrogen()->name();
|
|
||||||
Label done;
|
|
||||||
__ lw(object_map, FieldMemOperand(object, HeapObject::kMapOffset));
|
|
||||||
for (int i = 0; i < map_count; ++i) {
|
|
||||||
bool last = (i == map_count - 1);
|
|
||||||
Handle<Map> map = instr->hydrogen()->types()->at(i);
|
|
||||||
Label check_passed;
|
|
||||||
__ CompareMapAndBranch(object_map, map, &check_passed, eq, &check_passed);
|
|
||||||
if (last && !need_generic) {
|
|
||||||
DeoptimizeIf(al, instr->environment());
|
|
||||||
__ bind(&check_passed);
|
|
||||||
EmitLoadFieldOrConstantFunction(
|
|
||||||
result, object, map, name, instr->environment());
|
|
||||||
} else {
|
|
||||||
Label next;
|
|
||||||
__ Branch(&next);
|
|
||||||
__ bind(&check_passed);
|
|
||||||
EmitLoadFieldOrConstantFunction(
|
|
||||||
result, object, map, name, instr->environment());
|
|
||||||
__ Branch(&done);
|
|
||||||
__ bind(&next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (need_generic) {
|
|
||||||
__ li(a2, Operand(name));
|
|
||||||
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
|
||||||
}
|
|
||||||
__ bind(&done);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
||||||
ASSERT(ToRegister(instr->object()).is(a0));
|
ASSERT(ToRegister(instr->object()).is(a0));
|
||||||
ASSERT(ToRegister(instr->result()).is(v0));
|
ASSERT(ToRegister(instr->result()).is(v0));
|
||||||
|
@ -378,12 +378,6 @@ class LCodeGen BASE_EMBEDDED {
|
|||||||
// Caller should branch on equal condition.
|
// Caller should branch on equal condition.
|
||||||
void EmitIsConstructCall(Register temp1, Register temp2);
|
void EmitIsConstructCall(Register temp1, Register temp2);
|
||||||
|
|
||||||
void EmitLoadFieldOrConstantFunction(Register result,
|
|
||||||
Register object,
|
|
||||||
Handle<Map> type,
|
|
||||||
Handle<String> name,
|
|
||||||
LEnvironment* env);
|
|
||||||
|
|
||||||
// Emits optimized code to deep-copy the contents of statically known
|
// Emits optimized code to deep-copy the contents of statically known
|
||||||
// object graphs (e.g. object literal boilerplate).
|
// object graphs (e.g. object literal boilerplate).
|
||||||
void EmitDeepCopy(Handle<JSObject> object,
|
void EmitDeepCopy(Handle<JSObject> object,
|
||||||
|
@ -2067,23 +2067,6 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
|
|
||||||
HLoadNamedFieldPolymorphic* instr) {
|
|
||||||
ASSERT(instr->representation().IsTagged());
|
|
||||||
if (instr->need_generic()) {
|
|
||||||
LOperand* obj = UseFixed(instr->object(), a0);
|
|
||||||
LLoadNamedFieldPolymorphic* result =
|
|
||||||
new(zone()) LLoadNamedFieldPolymorphic(obj);
|
|
||||||
return MarkAsCall(DefineFixed(result, v0), instr);
|
|
||||||
} else {
|
|
||||||
LOperand* obj = UseRegisterAtStart(instr->object());
|
|
||||||
LLoadNamedFieldPolymorphic* result =
|
|
||||||
new(zone()) LLoadNamedFieldPolymorphic(obj);
|
|
||||||
return AssignEnvironment(DefineAsRegister(result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
|
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
|
||||||
LOperand* object = UseFixed(instr->object(), a0);
|
LOperand* object = UseFixed(instr->object(), a0);
|
||||||
LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(object), v0);
|
LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(object), v0);
|
||||||
|
@ -126,7 +126,6 @@ class LCodeGen;
|
|||||||
V(LoadKeyed) \
|
V(LoadKeyed) \
|
||||||
V(LoadKeyedGeneric) \
|
V(LoadKeyedGeneric) \
|
||||||
V(LoadNamedField) \
|
V(LoadNamedField) \
|
||||||
V(LoadNamedFieldPolymorphic) \
|
|
||||||
V(LoadNamedGeneric) \
|
V(LoadNamedGeneric) \
|
||||||
V(MapEnumLength) \
|
V(MapEnumLength) \
|
||||||
V(MathAbs) \
|
V(MathAbs) \
|
||||||
@ -1505,19 +1504,6 @@ class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
|
|
||||||
public:
|
|
||||||
explicit LLoadNamedFieldPolymorphic(LOperand* object) {
|
|
||||||
inputs_[0] = object;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOperand* object() { return inputs_[0]; }
|
|
||||||
|
|
||||||
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
|
class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
|
||||||
public:
|
public:
|
||||||
explicit LLoadNamedGeneric(LOperand* object) {
|
explicit LLoadNamedGeneric(LOperand* object) {
|
||||||
|
Loading…
Reference in New Issue
Block a user