Commit 0af05287 authored by ager@chromium.org's avatar ager@chromium.org

Support polymorphic loads of constant functions as well as fields.

R=fschneider@chromium.org
BUG=
TEST=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7792 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b4022f7b
......@@ -2284,23 +2284,29 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
void LCodeGen::EmitLoadField(Register result,
Register object,
Handle<Map> type,
Handle<String> name) {
void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name) {
LookupResult lookup;
type->LookupInDescriptors(NULL, *name, &lookup);
ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
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.
__ ldr(result, FieldMemOperand(object, offset + type->instance_size()));
ASSERT(lookup.IsProperty() &&
(lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
if (lookup.type() == FIELD) {
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.
__ ldr(result, FieldMemOperand(object, offset + type->instance_size()));
} else {
// Non-negative property indices are in the properties array.
__ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
__ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
}
} else {
// Non-negative property indices are in the properties array.
__ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
__ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
LoadHeapObject(result, Handle<HeapObject>::cast(function));
}
}
......@@ -2324,7 +2330,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
Label next;
__ cmp(scratch, Operand(map));
__ b(ne, &next);
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ b(&done);
__ bind(&next);
}
......@@ -2333,7 +2339,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
if (instr->hydrogen()->need_generic()) {
Label generic;
__ b(ne, &generic);
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ b(&done);
__ bind(&generic);
__ mov(r2, Operand(name));
......@@ -2341,7 +2347,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
DeoptimizeIf(ne, instr->environment());
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
}
__ bind(&done);
}
......
......@@ -284,10 +284,10 @@ class LCodeGen BASE_EMBEDDED {
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp1, Register temp2);
void EmitLoadField(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
void EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
LChunk* const chunk_;
MacroAssembler* const masm_;
......
......@@ -1206,13 +1206,23 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* object,
Handle<Map> map = types->at(i);
LookupResult lookup;
map->LookupInDescriptors(NULL, *name, &lookup);
if (lookup.IsProperty() && lookup.type() == FIELD) {
types_.Add(types->at(i));
int index = lookup.GetLocalFieldIndexFromMap(*map);
if (index < 0) {
SetFlag(kDependsOnInobjectFields);
} else {
SetFlag(kDependsOnBackingStoreFields);
if (lookup.IsProperty()) {
switch (lookup.type()) {
case FIELD: {
int index = lookup.GetLocalFieldIndexFromMap(*map);
if (index < 0) {
SetFlag(kDependsOnInobjectFields);
} else {
SetFlag(kDependsOnBackingStoreFields);
}
types_.Add(types->at(i));
break;
}
case CONSTANT_FUNCTION:
types_.Add(types->at(i));
break;
default:
break;
}
}
}
......
......@@ -2200,23 +2200,29 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
void LCodeGen::EmitLoadField(Register result,
Register object,
Handle<Map> type,
Handle<String> name) {
void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name) {
LookupResult lookup;
type->LookupInDescriptors(NULL, *name, &lookup);
ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
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.
__ mov(result, FieldOperand(object, offset + type->instance_size()));
ASSERT(lookup.IsProperty() &&
(lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
if (lookup.type() == FIELD) {
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.
__ mov(result, FieldOperand(object, offset + type->instance_size()));
} else {
// Non-negative property indices are in the properties array.
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
}
} else {
// Non-negative property indices are in the properties array.
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
LoadHeapObject(result, Handle<HeapObject>::cast(function));
}
}
......@@ -2239,7 +2245,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
NearLabel next;
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
__ j(not_equal, &next);
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ bind(&next);
}
......@@ -2248,7 +2254,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
if (instr->hydrogen()->need_generic()) {
NearLabel generic;
__ j(not_equal, &generic);
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ bind(&generic);
__ mov(ecx, name);
......@@ -2256,7 +2262,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
} else {
DeoptimizeIf(not_equal, instr->environment());
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
}
__ bind(&done);
}
......
......@@ -278,10 +278,10 @@ class LCodeGen BASE_EMBEDDED {
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp);
void EmitLoadField(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
void EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
LChunk* const chunk_;
MacroAssembler* const masm_;
......
......@@ -2208,23 +2208,29 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
void LCodeGen::EmitLoadField(Register result,
Register object,
Handle<Map> type,
Handle<String> name) {
void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name) {
LookupResult lookup;
type->LookupInDescriptors(NULL, *name, &lookup);
ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
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.
__ movq(result, FieldOperand(object, offset + type->instance_size()));
ASSERT(lookup.IsProperty() &&
(lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
if (lookup.type() == FIELD) {
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.
__ movq(result, FieldOperand(object, offset + type->instance_size()));
} else {
// Non-negative property indices are in the properties array.
__ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
}
} else {
// Non-negative property indices are in the properties array.
__ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
LoadHeapObject(result, Handle<HeapObject>::cast(function));
}
}
......@@ -2248,7 +2254,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
NearLabel next;
__ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
__ j(not_equal, &next);
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ bind(&next);
}
......@@ -2257,7 +2263,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
if (instr->hydrogen()->need_generic()) {
NearLabel generic;
__ j(not_equal, &generic);
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ bind(&generic);
__ Move(rcx, instr->hydrogen()->name());
......@@ -2265,7 +2271,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
DeoptimizeIf(not_equal, instr->environment());
EmitLoadField(result, object, map, name);
EmitLoadFieldOrConstantFunction(result, object, map, name);
}
__ bind(&done);
}
......
......@@ -264,10 +264,10 @@ class LCodeGen BASE_EMBEDDED {
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp);
void EmitLoadField(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
void EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
// Emits code for pushing either a tagged constant, a (non-double)
// register, or a stack slot operand.
......
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