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,13 +2284,15 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
void LCodeGen::EmitLoadField(Register result,
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);
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) {
......@@ -2302,6 +2304,10 @@ void LCodeGen::EmitLoadField(Register result,
__ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
__ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
}
} else {
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,7 +284,7 @@ class LCodeGen BASE_EMBEDDED {
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp1, Register temp2);
void EmitLoadField(Register result,
void EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
......
......@@ -1206,14 +1206,24 @@ 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));
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,13 +2200,15 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
void LCodeGen::EmitLoadField(Register result,
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);
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) {
......@@ -2218,6 +2220,10 @@ void LCodeGen::EmitLoadField(Register result,
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
}
} else {
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,7 +278,7 @@ class LCodeGen BASE_EMBEDDED {
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp);
void EmitLoadField(Register result,
void EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
......
......@@ -2208,13 +2208,15 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
void LCodeGen::EmitLoadField(Register result,
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);
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) {
......@@ -2226,6 +2228,10 @@ void LCodeGen::EmitLoadField(Register result,
__ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
__ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
}
} else {
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,7 +264,7 @@ class LCodeGen BASE_EMBEDDED {
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp);
void EmitLoadField(Register result,
void EmitLoadFieldOrConstantFunction(Register result,
Register object,
Handle<Map> type,
Handle<String> name);
......
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