Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 5b45b136e715058843daac836f282d3d1876e1f5..47c77b7e0a812a73d2b40ce04f5e48ef74af38cb 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -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); |
} |