Index: src/ia32/lithium-codegen-ia32.cc |
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
index d64f528e71c9a6d92221b2741df9c5cf4f82f7dd..5af85dd83ca70670bf28fb28ed7f524c255978b9 100644 |
--- a/src/ia32/lithium-codegen-ia32.cc |
+++ b/src/ia32/lithium-codegen-ia32.cc |
@@ -1837,6 +1837,50 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
} |
+void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
+ Register function = ToRegister(instr->function()); |
+ Register temp = ToRegister(instr->temporary()); |
+ Register result = ToRegister(instr->result()); |
+ |
+ // Check that the function really is a function. |
+ __ CmpObjectType(function, JS_FUNCTION_TYPE, result); |
+ DeoptimizeIf(not_equal, instr->environment()); |
+ |
+ // Check whether the function has an instance prototype. |
+ NearLabel non_instance; |
+ __ test_b(FieldOperand(result, Map::kBitFieldOffset), |
+ 1 << Map::kHasNonInstancePrototype); |
+ __ j(not_zero, &non_instance); |
+ |
+ // Get the prototype or initial map from the function. |
+ __ mov(result, |
+ FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
+ |
+ // If the prototype or initial map is the hole, don't return it and |
+ // simply miss the cache instead. This will allow us to allocate a |
fschneider
2010/12/21 17:57:52
This comment is not 100% up-to-date, since we deop
Vitaly Repeshko
2010/12/22 15:43:41
Updated.
|
+ // prototype object on-demand in the runtime system. |
+ __ cmp(Operand(result), Immediate(Factory::the_hole_value())); |
+ DeoptimizeIf(equal, instr->environment()); |
+ |
+ // If the function does not have an initial map, we're done. |
+ NearLabel done; |
+ __ CmpObjectType(result, MAP_TYPE, temp); |
+ __ j(not_equal, &done); |
+ |
+ // Get the prototype from the initial map. |
+ __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); |
+ __ jmp(&done); |
+ |
+ // Non-instance prototype: Fetch prototype from constructor field |
+ // in the function's map. |
+ __ bind(&non_instance); |
+ __ mov(result, FieldOperand(result, Map::kConstructorOffset)); |
+ |
+ // All done. |
+ __ bind(&done); |
+} |
+ |
+ |
void LCodeGen::DoLoadElements(LLoadElements* instr) { |
ASSERT(instr->result()->Equals(instr->input())); |
Register reg = ToRegister(instr->input()); |