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

Unified Diff: src/x64/codegen-x64.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
« src/arm/codegen-arm.cc ('K') | « src/arm/codegen-arm.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/codegen-x64.cc
===================================================================
--- src/x64/codegen-x64.cc (revision 2324)
+++ src/x64/codegen-x64.cc (working copy)
@@ -3367,11 +3367,67 @@
void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
- // TODO(X64): Optimize this like it's done on IA-32.
ASSERT(args->length() == 1);
+ JumpTarget leave, null, function, non_function_constructor;
Load(args->at(0)); // Load the object.
- Result result = frame_->CallRuntime(Runtime::kClassOf, 1);
- frame_->Push(&result);
+ Result obj = frame_->Pop();
+ obj.ToRegister();
+ frame_->Spill(obj.reg());
+
+ // If the object is a smi, we return null.
+ __ testl(obj.reg(), Immediate(kSmiTagMask));
Erik Corry 2009/07/02 13:48:31 Do we need an l here? Will that preclude an 8 bit
Mads Ager (chromium) 2009/07/02 14:14:08 I'm using testl for consistency with the rest of t
William Hesse 2009/07/02 14:44:25 testl does not preclude an 8-bit encoding of the i
+ null.Branch(zero);
+
+ // Check that the object is a JS object but take special care of JS
+ // functions to make sure they have 'Function' as their class.
+ { Result tmp = allocator()->Allocate();
+ __ movq(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
+ __ movb(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset));
+ __ cmpb(tmp.reg(), Immediate(FIRST_JS_OBJECT_TYPE));
Erik Corry 2009/07/02 13:48:31 CmpObjectType?
Mads Ager (chromium) 2009/07/02 14:14:08 Can't on x64/ia32 because the map register is clob
William Hesse 2009/07/02 14:44:25 On x64 and ia32, the map register isn't clobbered
+ null.Branch(less);
+
+ // 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);
+ __ cmpb(tmp.reg(), Immediate(JS_FUNCTION_TYPE));
+ function.Branch(equal);
+ }
+
+ // Check if the constructor in the map is a function.
+ { Result tmp = allocator()->Allocate();
+ __ movq(obj.reg(), FieldOperand(obj.reg(), Map::kConstructorOffset));
+ __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, tmp.reg());
William Hesse 2009/07/02 14:44:25 kScratchRegister, rather than tmp, can be used her
+ non_function_constructor.Branch(not_equal);
+ }
+
+ // The map register now contains the constructor function. Grab the
+ // instance class name from there.
+ __ movq(obj.reg(),
+ FieldOperand(obj.reg(), JSFunction::kSharedFunctionInfoOffset));
+ __ movq(obj.reg(),
+ FieldOperand(obj.reg(),
+ SharedFunctionInfo::kInstanceClassNameOffset));
+ frame_->Push(&obj);
+ leave.Jump();
+
+ // Functions have class 'Function'.
+ function.Bind();
+ frame_->Push(Factory::function_class_symbol());
+ leave.Jump();
+
+ // Objects with a non-function constructor have class 'Object'.
+ non_function_constructor.Bind();
+ frame_->Push(Factory::Object_symbol());
+ leave.Jump();
+
+ // Non-JS objects have class null.
+ null.Bind();
+ frame_->Push(Factory::null_value());
+
+ // All done.
+ leave.Bind();
}
« src/arm/codegen-arm.cc ('K') | « src/arm/codegen-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698