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

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 7918012: Unify the handling of comparinsons against null and undefined. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 3 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 3820 matching lines...) Expand 10 before | Expand all | Expand 10 after
3831 3831
3832 context()->Plug(rax); 3832 context()->Plug(rax);
3833 } else { 3833 } else {
3834 // This expression cannot throw a reference error at the top level. 3834 // This expression cannot throw a reference error at the top level.
3835 VisitInCurrentContext(expr); 3835 VisitInCurrentContext(expr);
3836 } 3836 }
3837 } 3837 }
3838 3838
3839 3839
3840 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, 3840 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
3841 Handle<String> check, 3841 Handle<String> check) {
3842 Label* if_true, 3842 Label materialize_true, materialize_false;
3843 Label* if_false, 3843 Label* if_true = NULL;
3844 Label* fall_through) { 3844 Label* if_false = NULL;
3845 Label* fall_through = NULL;
3846 context()->PrepareTest(&materialize_true, &materialize_false,
3847 &if_true, &if_false, &fall_through);
3848
3845 { AccumulatorValueContext context(this); 3849 { AccumulatorValueContext context(this);
3846 VisitForTypeofValue(expr); 3850 VisitForTypeofValue(expr);
3847 } 3851 }
3848 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3852 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3849 3853
3850 if (check->Equals(isolate()->heap()->number_symbol())) { 3854 if (check->Equals(isolate()->heap()->number_symbol())) {
3851 __ JumpIfSmi(rax, if_true); 3855 __ JumpIfSmi(rax, if_true);
3852 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); 3856 __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset));
3853 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); 3857 __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex);
3854 Split(equal, if_true, if_false, fall_through); 3858 Split(equal, if_true, if_false, fall_through);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3893 __ j(below, if_false); 3897 __ j(below, if_false);
3894 __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 3898 __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
3895 __ j(above, if_false); 3899 __ j(above, if_false);
3896 // Check for undetectable objects => false. 3900 // Check for undetectable objects => false.
3897 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 3901 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
3898 Immediate(1 << Map::kIsUndetectable)); 3902 Immediate(1 << Map::kIsUndetectable));
3899 Split(zero, if_true, if_false, fall_through); 3903 Split(zero, if_true, if_false, fall_through);
3900 } else { 3904 } else {
3901 if (if_false != fall_through) __ jmp(if_false); 3905 if (if_false != fall_through) __ jmp(if_false);
3902 } 3906 }
3903 } 3907 context()->Plug(if_true, if_false);
3904
3905
3906 void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
3907 Label* if_true,
3908 Label* if_false,
3909 Label* fall_through) {
3910 VisitForAccumulatorValue(expr);
3911 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3912
3913 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
3914 Split(equal, if_true, if_false, fall_through);
3915 } 3908 }
3916 3909
3917 3910
3918 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 3911 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
3919 Comment cmnt(masm_, "[ CompareOperation"); 3912 Comment cmnt(masm_, "[ CompareOperation");
3920 SetSourcePosition(expr->position()); 3913 SetSourcePosition(expr->position());
3921 3914
3915 // First we try a fast inlined version of the compare when one of
3916 // the operands is a literal.
3917 if (TryLiteralCompare(expr)) return;
3918
3922 // Always perform the comparison for its control flow. Pack the result 3919 // Always perform the comparison for its control flow. Pack the result
3923 // into the expression's context after the comparison is performed. 3920 // into the expression's context after the comparison is performed.
3924 Label materialize_true, materialize_false; 3921 Label materialize_true, materialize_false;
3925 Label* if_true = NULL; 3922 Label* if_true = NULL;
3926 Label* if_false = NULL; 3923 Label* if_false = NULL;
3927 Label* fall_through = NULL; 3924 Label* fall_through = NULL;
3928 context()->PrepareTest(&materialize_true, &materialize_false, 3925 context()->PrepareTest(&materialize_true, &materialize_false,
3929 &if_true, &if_false, &fall_through); 3926 &if_true, &if_false, &fall_through);
3930 3927
3931 // First we try a fast inlined version of the compare when one of
3932 // the operands is a literal.
3933 if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
3934 context()->Plug(if_true, if_false);
3935 return;
3936 }
3937
3938 Token::Value op = expr->op(); 3928 Token::Value op = expr->op();
3939 VisitForStackValue(expr->left()); 3929 VisitForStackValue(expr->left());
3940 switch (op) { 3930 switch (op) {
3941 case Token::IN: 3931 case Token::IN:
3942 VisitForStackValue(expr->right()); 3932 VisitForStackValue(expr->right());
3943 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 3933 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
3944 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 3934 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
3945 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 3935 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
3946 Split(equal, if_true, if_false, fall_through); 3936 Split(equal, if_true, if_false, fall_through);
3947 break; 3937 break;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
4016 Split(cc, if_true, if_false, fall_through); 4006 Split(cc, if_true, if_false, fall_through);
4017 } 4007 }
4018 } 4008 }
4019 4009
4020 // Convert the result of the comparison into one expected for this 4010 // Convert the result of the comparison into one expected for this
4021 // expression's context. 4011 // expression's context.
4022 context()->Plug(if_true, if_false); 4012 context()->Plug(if_true, if_false);
4023 } 4013 }
4024 4014
4025 4015
4026 void FullCodeGenerator::EmitLiteralCompareNull(Expression* expr, 4016 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
4027 bool is_strict, 4017 Expression* sub_expr,
4028 Label* if_true, 4018 NilValue nil) {
4029 Label* if_false, 4019 Label materialize_true, materialize_false;
4030 Label* fall_through) { 4020 Label* if_true = NULL;
4031 VisitForAccumulatorValue(expr); 4021 Label* if_false = NULL;
4022 Label* fall_through = NULL;
4023 context()->PrepareTest(&materialize_true, &materialize_false,
4024 &if_true, &if_false, &fall_through);
4025
4026 VisitForAccumulatorValue(sub_expr);
4032 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4027 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4033 __ CompareRoot(rax, Heap::kNullValueRootIndex); 4028 Heap::RootListIndex nil_value = nil == kNullValue ?
4034 if (is_strict) { 4029 Heap::kNullValueRootIndex :
4030 Heap::kUndefinedValueRootIndex;
4031 __ CompareRoot(rax, nil_value);
4032 if (expr->op() == Token::EQ_STRICT) {
4035 Split(equal, if_true, if_false, fall_through); 4033 Split(equal, if_true, if_false, fall_through);
4036 } else { 4034 } else {
4035 Heap::RootListIndex other_nil_value = nil == kNullValue ?
4036 Heap::kUndefinedValueRootIndex :
4037 Heap::kNullValueRootIndex;
4037 __ j(equal, if_true); 4038 __ j(equal, if_true);
4038 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 4039 __ CompareRoot(rax, other_nil_value);
4039 __ j(equal, if_true); 4040 __ j(equal, if_true);
4040 __ JumpIfSmi(rax, if_false); 4041 __ JumpIfSmi(rax, if_false);
4041 // It can be an undetectable object. 4042 // It can be an undetectable object.
4042 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 4043 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
4043 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 4044 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
4044 Immediate(1 << Map::kIsUndetectable)); 4045 Immediate(1 << Map::kIsUndetectable));
4045 Split(not_zero, if_true, if_false, fall_through); 4046 Split(not_zero, if_true, if_false, fall_through);
4046 } 4047 }
4048 context()->Plug(if_true, if_false);
4047 } 4049 }
4048 4050
4049 4051
4050 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4052 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4051 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 4053 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
4052 context()->Plug(rax); 4054 context()->Plug(rax);
4053 } 4055 }
4054 4056
4055 4057
4056 Register FullCodeGenerator::result_register() { 4058 Register FullCodeGenerator::result_register() {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4151 *context_length = 0; 4153 *context_length = 0;
4152 return previous_; 4154 return previous_;
4153 } 4155 }
4154 4156
4155 4157
4156 #undef __ 4158 #undef __
4157 4159
4158 } } // namespace v8::internal 4160 } } // namespace v8::internal
4159 4161
4160 #endif // V8_TARGET_ARCH_X64 4162 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/v8.h ('K') | « src/v8.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698