Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Unified Diff: src/arm/codegen-arm.cc

Issue 150226: Port %ClassOf() optimization to X64 and ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/x64/codegen-x64.cc » ('j') | src/x64/codegen-x64.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 2324)
+++ src/arm/codegen-arm.cc (working copy)
@@ -3176,9 +3176,62 @@
void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope;
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0)); // Load the object.
- frame_->CallRuntime(Runtime::kClassOf, 1);
+ JumpTarget leave, null, function, non_function_constructor;
+
+ // Load the object into r0.
+ LoadAndSpill(args->at(0));
+ frame_->EmitPop(r0);
+
+ // If the object is a smi, we return null.
+ __ tst(r0, Operand(kSmiTagMask));
+ null.Branch(eq);
Erik Corry 2009/07/02 13:48:31 Ideally I'd like to do this as a conditional move
+
+ // Check that the object is a JS object but take special care of JS
+ // functions to make sure they have 'Function' as their class.
+ __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
+ __ ldrb(r1, FieldMemOperand(r0, Map::kInstanceTypeOffset));
+ __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
Erik Corry 2009/07/02 13:48:31 You can do these 3 in one with __ CompareObjectTyp
Mads Ager (chromium) 2009/07/02 14:14:08 Ah, yes, there is one more register parameter to C
+ null.Branch(lt);
+
+ // As long as JS_FUNCTION_TYPE is the last instance type and it is
+ // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
+ // LAST_JS_OBJECT_TYPE.
+ ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
+ __ cmp(r1, Operand(JS_FUNCTION_TYPE));
+ function.Branch(eq);
+
+ // Check if the constructor in the map is a function.
+ __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset));
+ __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
Erik Corry 2009/07/02 13:48:31 r0 = Object. r1 = Map. r1 = type (overwrites map)
Mads Ager (chromium) 2009/07/02 14:14:08 Yes, that is fine. All I need is for the construc
+ non_function_constructor.Branch(ne);
+
+ // The map register now contains the constructor function. Grab the
Erik Corry 2009/07/02 13:48:31 Map register is r0? I think r0 is the constructor
Mads Ager (chromium) 2009/07/02 14:14:08 Yeah, strange comment. Changed it to 'The r0 regi
+ // instance class name from there.
+ __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
+ __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset));
frame_->EmitPush(r0);
+ leave.Jump();
+
+ // Functions have class 'Function'.
+ function.Bind();
+ __ mov(r0, Operand(Factory::function_class_symbol()));
+ frame_->EmitPush(r0);
+ leave.Jump();
+
+ // Objects with a non-function constructor have class 'Object'.
+ non_function_constructor.Bind();
+ __ mov(r0, Operand(Factory::Object_symbol()));
+ frame_->EmitPush(r0);
+ leave.Jump();
+
+ // Non-JS objects have class null.
+ null.Bind();
+ __ mov(r0, Operand(Factory::null_value()));
+ frame_->EmitPush(r0);
+
+ // All done.
+ leave.Bind();
}
« no previous file with comments | « no previous file | src/x64/codegen-x64.cc » ('j') | src/x64/codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698