Chromium Code Reviews| Index: src/arm/lithium-codegen-arm.cc |
| =================================================================== |
| --- src/arm/lithium-codegen-arm.cc (revision 7299) |
| +++ src/arm/lithium-codegen-arm.cc (working copy) |
| @@ -2175,6 +2175,72 @@ |
| } |
| +void LCodeGen::EmitLoadField(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())); |
| + } else { |
| + // Non-negative property indices are in the properties array. |
| + __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| + __ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize)); |
| + } |
| +} |
| + |
| + |
| +void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { |
| + Register object = ToRegister(instr->object()); |
| + Register result = ToRegister(instr->result()); |
| + Register scratch = scratch0(); |
| + int map_count = instr->hydrogen()->types()->length(); |
| + Handle<String> name = instr->hydrogen()->name(); |
| + if (map_count == 0) { |
| + ASSERT(instr->hydrogen()->need_generic()); |
| + __ mov(r2, Operand(name)); |
| + Handle<Code> ic( |
| + isolate()->builtins()->builtin(Builtins::LoadIC_Initialize)); |
| + CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| + } else { |
| + Label done; |
| + __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
| + for (int i = 0; i < map_count - 1; ++i) { |
| + Handle<Map> map = instr->hydrogen()->types()->at(i); |
| + Label next; |
| + __ cmp(scratch, Operand(map)); |
| + __ b(ne, &next); |
| + EmitLoadField(result, object, map, name); |
| + __ b(&done); |
| + __ bind(&next); |
| + } |
| + Handle<Map> map = instr->hydrogen()->types()->last(); |
| + __ cmp(scratch, Operand(map)); |
| + if (instr->hydrogen()->need_generic()) { |
| + Label generic; |
| + __ b(ne, &generic); |
| + EmitLoadField(result, object, map, name); |
|
Kevin Millikin (Chromium)
2011/03/24 09:28:25
BTW, you can write a single call to EmitLoadField
|
| + __ b(&done); |
| + __ bind(&generic); |
| + __ mov(r2, Operand(name)); |
| + Handle<Code> ic( |
| + isolate()->builtins()->builtin(Builtins::LoadIC_Initialize)); |
| + CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| + } else { |
| + DeoptimizeIf(ne, instr->environment()); |
| + EmitLoadField(result, object, map, name); |
| + } |
| + __ bind(&done); |
| + } |
| +} |
| + |
| + |
| void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| ASSERT(ToRegister(instr->object()).is(r0)); |
| ASSERT(ToRegister(instr->result()).is(r0)); |