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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 6992072: Implement set trap for proxies, and revamp class hierarchy in preparation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Renamed range constants for InstanceType enum. Created 9 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // We don't use CmpObjectType because we manipulate the type field. 259 // We don't use CmpObjectType because we manipulate the type field.
260 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 260 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
261 __ movzxbq(rcx, FieldOperand(rdx, Map::kInstanceTypeOffset)); 261 __ movzxbq(rcx, FieldOperand(rdx, Map::kInstanceTypeOffset));
262 262
263 // Undetectable => false. 263 // Undetectable => false.
264 __ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset)); 264 __ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset));
265 __ and_(rbx, Immediate(1 << Map::kIsUndetectable)); 265 __ and_(rbx, Immediate(1 << Map::kIsUndetectable));
266 __ j(not_zero, &false_result, Label::kNear); 266 __ j(not_zero, &false_result, Label::kNear);
267 267
268 // JavaScript object => true. 268 // JavaScript object => true.
269 __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE)); 269 __ cmpq(rcx, Immediate(FIRST_SPEC_OBJECT_TYPE));
270 __ j(above_equal, &true_result, Label::kNear); 270 __ j(above_equal, &true_result, Label::kNear);
271 271
272 // String value => false iff empty. 272 // String value => false iff empty.
273 __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE)); 273 __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
274 __ j(above_equal, &not_string, Label::kNear); 274 __ j(above_equal, &not_string, Label::kNear);
275 __ movq(rdx, FieldOperand(rax, String::kLengthOffset)); 275 __ movq(rdx, FieldOperand(rax, String::kLengthOffset));
276 __ SmiTest(rdx); 276 __ SmiTest(rdx);
277 __ j(zero, &false_result, Label::kNear); 277 __ j(zero, &false_result, Label::kNear);
278 __ jmp(&true_result, Label::kNear); 278 __ jmp(&true_result, Label::kNear);
279 279
(...skipping 2430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2710 if (never_nan_nan_ && (cc_ == equal)) { 2710 if (never_nan_nan_ && (cc_ == equal)) {
2711 __ Set(rax, EQUAL); 2711 __ Set(rax, EQUAL);
2712 __ ret(0); 2712 __ ret(0);
2713 } else { 2713 } else {
2714 Label heap_number; 2714 Label heap_number;
2715 // If it's not a heap number, then return equal for (in)equality operator. 2715 // If it's not a heap number, then return equal for (in)equality operator.
2716 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), 2716 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
2717 factory->heap_number_map()); 2717 factory->heap_number_map());
2718 __ j(equal, &heap_number, Label::kNear); 2718 __ j(equal, &heap_number, Label::kNear);
2719 if (cc_ != equal) { 2719 if (cc_ != equal) {
2720 // Call runtime on identical JSObjects. Otherwise return equal. 2720 // Call runtime on identical objects. Otherwise return equal.
2721 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx); 2721 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
2722 __ j(above_equal, &not_identical, Label::kNear); 2722 __ j(above_equal, &not_identical, Label::kNear);
2723 } 2723 }
2724 __ Set(rax, EQUAL); 2724 __ Set(rax, EQUAL);
2725 __ ret(0); 2725 __ ret(0);
2726 2726
2727 __ bind(&heap_number); 2727 __ bind(&heap_number);
2728 // It is a heap number, so return equal if it's not NaN. 2728 // It is a heap number, so return equal if it's not NaN.
2729 // For NaN, return 1 for every condition except greater and 2729 // For NaN, return 1 for every condition except greater and
2730 // greater-equal. Return -1 for them, so the comparison yields 2730 // greater-equal. Return -1 for them, so the comparison yields
2731 // false for all conditions except not-equal. 2731 // false for all conditions except not-equal.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2767 __ ret(0); 2767 __ ret(0);
2768 2768
2769 __ bind(&not_smis); 2769 __ bind(&not_smis);
2770 } 2770 }
2771 2771
2772 // If either operand is a JSObject or an oddball value, then they are not 2772 // If either operand is a JSObject or an oddball value, then they are not
2773 // equal since their pointers are different 2773 // equal since their pointers are different
2774 // There is no test for undetectability in strict equality. 2774 // There is no test for undetectability in strict equality.
2775 2775
2776 // If the first object is a JS object, we have done pointer comparison. 2776 // If the first object is a JS object, we have done pointer comparison.
2777 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 2777 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
2778 Label first_non_object; 2778 Label first_non_object;
2779 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx); 2779 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
2780 __ j(below, &first_non_object, Label::kNear); 2780 __ j(below, &first_non_object, Label::kNear);
2781 // Return non-zero (eax (not rax) is not zero) 2781 // Return non-zero (eax (not rax) is not zero)
2782 Label return_not_equal; 2782 Label return_not_equal;
2783 STATIC_ASSERT(kHeapObjectTag != 0); 2783 STATIC_ASSERT(kHeapObjectTag != 0);
2784 __ bind(&return_not_equal); 2784 __ bind(&return_not_equal);
2785 __ ret(0); 2785 __ ret(0);
2786 2786
2787 __ bind(&first_non_object); 2787 __ bind(&first_non_object);
2788 // Check for oddballs: true, false, null, undefined. 2788 // Check for oddballs: true, false, null, undefined.
2789 __ CmpInstanceType(rcx, ODDBALL_TYPE); 2789 __ CmpInstanceType(rcx, ODDBALL_TYPE);
2790 __ j(equal, &return_not_equal); 2790 __ j(equal, &return_not_equal);
2791 2791
2792 __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx); 2792 __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx);
2793 __ j(above_equal, &return_not_equal); 2793 __ j(above_equal, &return_not_equal);
2794 2794
2795 // Check for oddballs: true, false, null, undefined. 2795 // Check for oddballs: true, false, null, undefined.
2796 __ CmpInstanceType(rcx, ODDBALL_TYPE); 2796 __ CmpInstanceType(rcx, ODDBALL_TYPE);
2797 __ j(equal, &return_not_equal); 2797 __ j(equal, &return_not_equal);
2798 2798
2799 // Fall through to the general case. 2799 // Fall through to the general case.
2800 } 2800 }
2801 __ bind(&slow); 2801 __ bind(&slow);
2802 } 2802 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 // and their pointers are different. 2878 // and their pointers are different.
2879 Label not_both_objects, return_unequal; 2879 Label not_both_objects, return_unequal;
2880 // At most one is a smi, so we can test for smi by adding the two. 2880 // At most one is a smi, so we can test for smi by adding the two.
2881 // A smi plus a heap object has the low bit set, a heap object plus 2881 // A smi plus a heap object has the low bit set, a heap object plus
2882 // a heap object has the low bit clear. 2882 // a heap object has the low bit clear.
2883 STATIC_ASSERT(kSmiTag == 0); 2883 STATIC_ASSERT(kSmiTag == 0);
2884 STATIC_ASSERT(kSmiTagMask == 1); 2884 STATIC_ASSERT(kSmiTagMask == 1);
2885 __ lea(rcx, Operand(rax, rdx, times_1, 0)); 2885 __ lea(rcx, Operand(rax, rdx, times_1, 0));
2886 __ testb(rcx, Immediate(kSmiTagMask)); 2886 __ testb(rcx, Immediate(kSmiTagMask));
2887 __ j(not_zero, &not_both_objects, Label::kNear); 2887 __ j(not_zero, &not_both_objects, Label::kNear);
2888 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx); 2888 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx);
2889 __ j(below, &not_both_objects, Label::kNear); 2889 __ j(below, &not_both_objects, Label::kNear);
2890 __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx); 2890 __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx);
2891 __ j(below, &not_both_objects, Label::kNear); 2891 __ j(below, &not_both_objects, Label::kNear);
2892 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), 2892 __ testb(FieldOperand(rbx, Map::kBitFieldOffset),
2893 Immediate(1 << Map::kIsUndetectable)); 2893 Immediate(1 << Map::kIsUndetectable));
2894 __ j(zero, &return_unequal, Label::kNear); 2894 __ j(zero, &return_unequal, Label::kNear);
2895 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 2895 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
2896 Immediate(1 << Map::kIsUndetectable)); 2896 Immediate(1 << Map::kIsUndetectable));
2897 __ j(zero, &return_unequal, Label::kNear); 2897 __ j(zero, &return_unequal, Label::kNear);
2898 // The objects are both undetectable, so they both compare as the value 2898 // The objects are both undetectable, so they both compare as the value
2899 // undefined, and are equal. 2899 // undefined, and are equal.
2900 __ Set(rax, EQUAL); 2900 __ Set(rax, EQUAL);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2957 if (ReceiverMightBeValue()) { 2957 if (ReceiverMightBeValue()) {
2958 // Get the receiver from the stack. 2958 // Get the receiver from the stack.
2959 // +1 ~ return address 2959 // +1 ~ return address
2960 Label receiver_is_value, receiver_is_js_object; 2960 Label receiver_is_value, receiver_is_js_object;
2961 __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize)); 2961 __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
2962 2962
2963 // Check if receiver is a smi (which is a number value). 2963 // Check if receiver is a smi (which is a number value).
2964 __ JumpIfSmi(rax, &receiver_is_value); 2964 __ JumpIfSmi(rax, &receiver_is_value);
2965 2965
2966 // Check if the receiver is a valid JS object. 2966 // Check if the receiver is a valid JS object.
2967 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdi); 2967 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rdi);
2968 __ j(above_equal, &receiver_is_js_object); 2968 __ j(above_equal, &receiver_is_js_object);
2969 2969
2970 // Call the runtime to box the value. 2970 // Call the runtime to box the value.
2971 __ bind(&receiver_is_value); 2971 __ bind(&receiver_is_value);
2972 __ EnterInternalFrame(); 2972 __ EnterInternalFrame();
2973 __ push(rax); 2973 __ push(rax);
2974 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 2974 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
2975 __ LeaveInternalFrame(); 2975 __ LeaveInternalFrame();
2976 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rax); 2976 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rax);
2977 2977
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
3408 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); 3408 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
3409 int extra_stack_space = HasCallSiteInlineCheck() ? kPointerSize : 0; 3409 int extra_stack_space = HasCallSiteInlineCheck() ? kPointerSize : 0;
3410 3410
3411 // Get the object - go slow case if it's a smi. 3411 // Get the object - go slow case if it's a smi.
3412 Label slow; 3412 Label slow;
3413 3413
3414 __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space)); 3414 __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space));
3415 __ JumpIfSmi(rax, &slow); 3415 __ JumpIfSmi(rax, &slow);
3416 3416
3417 // Check that the left hand is a JS object. Leave its map in rax. 3417 // Check that the left hand is a JS object. Leave its map in rax.
3418 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax); 3418 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax);
3419 __ j(below, &slow); 3419 __ j(below, &slow);
3420 __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE); 3420 __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE);
3421 __ j(above, &slow); 3421 __ j(above, &slow);
3422 3422
3423 // Get the prototype of the function. 3423 // Get the prototype of the function.
3424 __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space)); 3424 __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space));
3425 // rdx is function, rax is map. 3425 // rdx is function, rax is map.
3426 3426
3427 // If there is a call site cache don't look in the global cache, but do the 3427 // If there is a call site cache don't look in the global cache, but do the
3428 // real lookup and update the call site cache. 3428 // real lookup and update the call site cache.
3429 if (!HasCallSiteInlineCheck()) { 3429 if (!HasCallSiteInlineCheck()) {
3430 // Look up the function and the map in the instanceof cache. 3430 // Look up the function and the map in the instanceof cache.
3431 Label miss; 3431 Label miss;
3432 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); 3432 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
3433 __ j(not_equal, &miss, Label::kNear); 3433 __ j(not_equal, &miss, Label::kNear);
3434 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex); 3434 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex);
3435 __ j(not_equal, &miss, Label::kNear); 3435 __ j(not_equal, &miss, Label::kNear);
3436 __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); 3436 __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
3437 __ ret(2 * kPointerSize); 3437 __ ret(2 * kPointerSize);
3438 __ bind(&miss); 3438 __ bind(&miss);
3439 } 3439 }
3440 3440
3441 __ TryGetFunctionPrototype(rdx, rbx, &slow); 3441 __ TryGetFunctionPrototype(rdx, rbx, &slow);
3442 3442
3443 // Check that the function prototype is a JS object. 3443 // Check that the function prototype is a JS object.
3444 __ JumpIfSmi(rbx, &slow); 3444 __ JumpIfSmi(rbx, &slow);
3445 __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister); 3445 __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
3446 __ j(below, &slow); 3446 __ j(below, &slow);
3447 __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE); 3447 __ CmpInstanceType(kScratchRegister, LAST_SPEC_OBJECT_TYPE);
3448 __ j(above, &slow); 3448 __ j(above, &slow);
3449 3449
3450 // Register mapping: 3450 // Register mapping:
3451 // rax is object map. 3451 // rax is object map.
3452 // rdx is function. 3452 // rdx is function.
3453 // rbx is function prototype. 3453 // rbx is function prototype.
3454 if (!HasCallSiteInlineCheck()) { 3454 if (!HasCallSiteInlineCheck()) {
3455 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); 3455 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
3456 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex); 3456 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex);
3457 } else { 3457 } else {
(...skipping 1666 matching lines...) Expand 10 before | Expand all | Expand 10 after
5124 __ Drop(1); 5124 __ Drop(1);
5125 __ ret(2 * kPointerSize); 5125 __ ret(2 * kPointerSize);
5126 } 5126 }
5127 5127
5128 5128
5129 #undef __ 5129 #undef __
5130 5130
5131 } } // namespace v8::internal 5131 } } // namespace v8::internal
5132 5132
5133 #endif // V8_TARGET_ARCH_X64 5133 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698