OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3360 frame_->Push(&result); | 3360 frame_->Push(&result); |
3361 } | 3361 } |
3362 | 3362 |
3363 | 3363 |
3364 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { | 3364 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { |
3365 UNIMPLEMENTED(); | 3365 UNIMPLEMENTED(); |
3366 } | 3366 } |
3367 | 3367 |
3368 | 3368 |
3369 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { | 3369 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { |
3370 // TODO(X64): Optimize this like it's done on IA-32. | |
3371 ASSERT(args->length() == 1); | 3370 ASSERT(args->length() == 1); |
3371 JumpTarget leave, null, function, non_function_constructor; | |
3372 Load(args->at(0)); // Load the object. | 3372 Load(args->at(0)); // Load the object. |
3373 Result result = frame_->CallRuntime(Runtime::kClassOf, 1); | 3373 Result obj = frame_->Pop(); |
3374 frame_->Push(&result); | 3374 obj.ToRegister(); |
3375 frame_->Spill(obj.reg()); | |
3376 | |
3377 // If the object is a smi, we return null. | |
3378 __ 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
| |
3379 null.Branch(zero); | |
3380 | |
3381 // Check that the object is a JS object but take special care of JS | |
3382 // functions to make sure they have 'Function' as their class. | |
3383 { Result tmp = allocator()->Allocate(); | |
3384 __ movq(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset)); | |
3385 __ movb(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset)); | |
3386 __ 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
| |
3387 null.Branch(less); | |
3388 | |
3389 // As long as JS_FUNCTION_TYPE is the last instance type and it is | |
3390 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for | |
3391 // LAST_JS_OBJECT_TYPE. | |
3392 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | |
3393 ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); | |
3394 __ cmpb(tmp.reg(), Immediate(JS_FUNCTION_TYPE)); | |
3395 function.Branch(equal); | |
3396 } | |
3397 | |
3398 // Check if the constructor in the map is a function. | |
3399 { Result tmp = allocator()->Allocate(); | |
3400 __ movq(obj.reg(), FieldOperand(obj.reg(), Map::kConstructorOffset)); | |
3401 __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, tmp.reg()); | |
William Hesse
2009/07/02 14:44:25
kScratchRegister, rather than tmp, can be used her
| |
3402 non_function_constructor.Branch(not_equal); | |
3403 } | |
3404 | |
3405 // The map register now contains the constructor function. Grab the | |
3406 // instance class name from there. | |
3407 __ movq(obj.reg(), | |
3408 FieldOperand(obj.reg(), JSFunction::kSharedFunctionInfoOffset)); | |
3409 __ movq(obj.reg(), | |
3410 FieldOperand(obj.reg(), | |
3411 SharedFunctionInfo::kInstanceClassNameOffset)); | |
3412 frame_->Push(&obj); | |
3413 leave.Jump(); | |
3414 | |
3415 // Functions have class 'Function'. | |
3416 function.Bind(); | |
3417 frame_->Push(Factory::function_class_symbol()); | |
3418 leave.Jump(); | |
3419 | |
3420 // Objects with a non-function constructor have class 'Object'. | |
3421 non_function_constructor.Bind(); | |
3422 frame_->Push(Factory::Object_symbol()); | |
3423 leave.Jump(); | |
3424 | |
3425 // Non-JS objects have class null. | |
3426 null.Bind(); | |
3427 frame_->Push(Factory::null_value()); | |
3428 | |
3429 // All done. | |
3430 leave.Bind(); | |
3375 } | 3431 } |
3376 | 3432 |
3377 | 3433 |
3378 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { | 3434 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { |
3379 ASSERT(args->length() == 2); | 3435 ASSERT(args->length() == 2); |
3380 JumpTarget leave; | 3436 JumpTarget leave; |
3381 Load(args->at(0)); // Load the object. | 3437 Load(args->at(0)); // Load the object. |
3382 Load(args->at(1)); // Load the value. | 3438 Load(args->at(1)); // Load the value. |
3383 Result value = frame_->Pop(); | 3439 Result value = frame_->Pop(); |
3384 Result object = frame_->Pop(); | 3440 Result object = frame_->Pop(); |
(...skipping 3453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6838 int CompareStub::MinorKey() { | 6894 int CompareStub::MinorKey() { |
6839 // Encode the two parameters in a unique 16 bit value. | 6895 // Encode the two parameters in a unique 16 bit value. |
6840 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 6896 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
6841 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 6897 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
6842 } | 6898 } |
6843 | 6899 |
6844 | 6900 |
6845 #undef __ | 6901 #undef __ |
6846 | 6902 |
6847 } } // namespace v8::internal | 6903 } } // namespace v8::internal |
OLD | NEW |