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

Side by Side Diff: src/ia32/full-codegen-ia32.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 3943 matching lines...) Expand 10 before | Expand all | Expand 10 after
3954 3954
3955 context()->Plug(eax); 3955 context()->Plug(eax);
3956 } else { 3956 } else {
3957 // This expression cannot throw a reference error at the top level. 3957 // This expression cannot throw a reference error at the top level.
3958 VisitInCurrentContext(expr); 3958 VisitInCurrentContext(expr);
3959 } 3959 }
3960 } 3960 }
3961 3961
3962 3962
3963 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, 3963 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
3964 Handle<String> check, 3964 Handle<String> check) {
3965 Label* if_true, 3965 Label materialize_true, materialize_false;
3966 Label* if_false, 3966 Label* if_true = NULL;
3967 Label* fall_through) { 3967 Label* if_false = NULL;
3968 Label* fall_through = NULL;
3969 context()->PrepareTest(&materialize_true, &materialize_false,
3970 &if_true, &if_false, &fall_through);
3971
3968 { AccumulatorValueContext context(this); 3972 { AccumulatorValueContext context(this);
3969 VisitForTypeofValue(expr); 3973 VisitForTypeofValue(expr);
3970 } 3974 }
3971 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3975 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3972 3976
3973 if (check->Equals(isolate()->heap()->number_symbol())) { 3977 if (check->Equals(isolate()->heap()->number_symbol())) {
3974 __ JumpIfSmi(eax, if_true); 3978 __ JumpIfSmi(eax, if_true);
3975 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3979 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3976 isolate()->factory()->heap_number_map()); 3980 isolate()->factory()->heap_number_map());
3977 Split(equal, if_true, if_false, fall_through); 3981 Split(equal, if_true, if_false, fall_through);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4015 __ j(below, if_false); 4019 __ j(below, if_false);
4016 __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4020 __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4017 __ j(above, if_false); 4021 __ j(above, if_false);
4018 // Check for undetectable objects => false. 4022 // Check for undetectable objects => false.
4019 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), 4023 __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
4020 1 << Map::kIsUndetectable); 4024 1 << Map::kIsUndetectable);
4021 Split(zero, if_true, if_false, fall_through); 4025 Split(zero, if_true, if_false, fall_through);
4022 } else { 4026 } else {
4023 if (if_false != fall_through) __ jmp(if_false); 4027 if (if_false != fall_through) __ jmp(if_false);
4024 } 4028 }
4025 } 4029 context()->Plug(if_true, if_false);
4026
4027
4028 void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
4029 Label* if_true,
4030 Label* if_false,
4031 Label* fall_through) {
4032 VisitForAccumulatorValue(expr);
4033 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4034
4035 __ cmp(eax, isolate()->factory()->undefined_value());
4036 Split(equal, if_true, if_false, fall_through);
4037 } 4030 }
4038 4031
4039 4032
4040 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 4033 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
4041 Comment cmnt(masm_, "[ CompareOperation"); 4034 Comment cmnt(masm_, "[ CompareOperation");
4042 SetSourcePosition(expr->position()); 4035 SetSourcePosition(expr->position());
4043 4036
4037 // First we try a fast inlined version of the compare when one of
4038 // the operands is a literal.
4039 if (TryLiteralCompare(expr)) return;
4040
4044 // Always perform the comparison for its control flow. Pack the result 4041 // Always perform the comparison for its control flow. Pack the result
4045 // into the expression's context after the comparison is performed. 4042 // into the expression's context after the comparison is performed.
4046
4047 Label materialize_true, materialize_false; 4043 Label materialize_true, materialize_false;
4048 Label* if_true = NULL; 4044 Label* if_true = NULL;
4049 Label* if_false = NULL; 4045 Label* if_false = NULL;
4050 Label* fall_through = NULL; 4046 Label* fall_through = NULL;
4051 context()->PrepareTest(&materialize_true, &materialize_false, 4047 context()->PrepareTest(&materialize_true, &materialize_false,
4052 &if_true, &if_false, &fall_through); 4048 &if_true, &if_false, &fall_through);
4053 4049
4054 // First we try a fast inlined version of the compare when one of
4055 // the operands is a literal.
4056 if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
4057 context()->Plug(if_true, if_false);
4058 return;
4059 }
4060
4061 Token::Value op = expr->op(); 4050 Token::Value op = expr->op();
4062 VisitForStackValue(expr->left()); 4051 VisitForStackValue(expr->left());
4063 switch (expr->op()) { 4052 switch (op) {
4064 case Token::IN: 4053 case Token::IN:
4065 VisitForStackValue(expr->right()); 4054 VisitForStackValue(expr->right());
4066 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4055 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
4067 decrement_stack_height(2); 4056 decrement_stack_height(2);
4068 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4057 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
4069 __ cmp(eax, isolate()->factory()->true_value()); 4058 __ cmp(eax, isolate()->factory()->true_value());
4070 Split(equal, if_true, if_false, fall_through); 4059 Split(equal, if_true, if_false, fall_through);
4071 break; 4060 break;
4072 4061
4073 case Token::INSTANCEOF: { 4062 case Token::INSTANCEOF: {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4144 Split(cc, if_true, if_false, fall_through); 4133 Split(cc, if_true, if_false, fall_through);
4145 } 4134 }
4146 } 4135 }
4147 4136
4148 // Convert the result of the comparison into one expected for this 4137 // Convert the result of the comparison into one expected for this
4149 // expression's context. 4138 // expression's context.
4150 context()->Plug(if_true, if_false); 4139 context()->Plug(if_true, if_false);
4151 } 4140 }
4152 4141
4153 4142
4154 void FullCodeGenerator::EmitLiteralCompareNull(Expression* expr, 4143 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
4155 bool is_strict, 4144 Expression* sub_expr,
4156 Label* if_true, 4145 NilValue nil) {
4157 Label* if_false, 4146 Label materialize_true, materialize_false;
4158 Label* fall_through) { 4147 Label* if_true = NULL;
4159 VisitForAccumulatorValue(expr); 4148 Label* if_false = NULL;
4149 Label* fall_through = NULL;
4150 context()->PrepareTest(&materialize_true, &materialize_false,
4151 &if_true, &if_false, &fall_through);
4152
4153 VisitForAccumulatorValue(sub_expr);
4160 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4154 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4161 __ cmp(eax, isolate()->factory()->null_value()); 4155 Handle<Object> nil_value = nil == kNullValue ?
4162 if (is_strict) { 4156 isolate()->factory()->null_value() :
4157 isolate()->factory()->undefined_value();
4158 __ cmp(eax, nil_value);
4159 if (expr->op() == Token::EQ_STRICT) {
4163 Split(equal, if_true, if_false, fall_through); 4160 Split(equal, if_true, if_false, fall_through);
4164 } else { 4161 } else {
4162 Handle<Object> other_nil_value = nil == kNullValue ?
4163 isolate()->factory()->undefined_value() :
4164 isolate()->factory()->null_value();
4165 __ j(equal, if_true); 4165 __ j(equal, if_true);
4166 __ cmp(eax, isolate()->factory()->undefined_value()); 4166 __ cmp(eax, other_nil_value);
4167 __ j(equal, if_true); 4167 __ j(equal, if_true);
4168 __ JumpIfSmi(eax, if_false); 4168 __ JumpIfSmi(eax, if_false);
4169 // It can be an undetectable object. 4169 // It can be an undetectable object.
4170 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 4170 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
4171 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset)); 4171 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset));
4172 __ test(edx, Immediate(1 << Map::kIsUndetectable)); 4172 __ test(edx, Immediate(1 << Map::kIsUndetectable));
4173 Split(not_zero, if_true, if_false, fall_through); 4173 Split(not_zero, if_true, if_false, fall_through);
4174 } 4174 }
4175 context()->Plug(if_true, if_false);
4175 } 4176 }
4176 4177
4177 4178
4178 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4179 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4179 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4180 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4180 context()->Plug(eax); 4181 context()->Plug(eax);
4181 } 4182 }
4182 4183
4183 4184
4184 Register FullCodeGenerator::result_register() { 4185 Register FullCodeGenerator::result_register() {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
4276 *context_length = 0; 4277 *context_length = 0;
4277 return previous_; 4278 return previous_;
4278 } 4279 }
4279 4280
4280 4281
4281 #undef __ 4282 #undef __
4282 4283
4283 } } // namespace v8::internal 4284 } } // namespace v8::internal
4284 4285
4285 #endif // V8_TARGET_ARCH_IA32 4286 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | src/v8.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698