OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 5136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5147 __ Push(ToHandle(LConstantOperand::cast(operand))); | 5147 __ Push(ToHandle(LConstantOperand::cast(operand))); |
5148 } else if (operand->IsRegister()) { | 5148 } else if (operand->IsRegister()) { |
5149 __ push(ToRegister(operand)); | 5149 __ push(ToRegister(operand)); |
5150 } else { | 5150 } else { |
5151 __ push(ToOperand(operand)); | 5151 __ push(ToOperand(operand)); |
5152 } | 5152 } |
5153 } | 5153 } |
5154 | 5154 |
5155 | 5155 |
5156 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 5156 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 5157 Representation rep = instr->hydrogen()->value()->representation(); |
| 5158 if (rep.IsSpecialization()) { |
| 5159 if (instr->hydrogen()->CheckNumberString()) { |
| 5160 EmitGoto(instr->TrueDestination(chunk_)); |
| 5161 } else { |
| 5162 EmitGoto(instr->FalseDestination(chunk_)); |
| 5163 } |
| 5164 return; |
| 5165 } |
| 5166 |
5157 Register input = ToRegister(instr->value()); | 5167 Register input = ToRegister(instr->value()); |
5158 | 5168 Condition final_branch_condition = EmitTypeofIs(instr, input); |
5159 Condition final_branch_condition = | |
5160 EmitTypeofIs(instr->TrueLabel(chunk_), | |
5161 instr->FalseLabel(chunk_), input, instr->type_literal()); | |
5162 if (final_branch_condition != no_condition) { | 5169 if (final_branch_condition != no_condition) { |
5163 EmitBranch(instr, final_branch_condition); | 5170 EmitBranch(instr, final_branch_condition); |
5164 } | 5171 } |
5165 } | 5172 } |
5166 | 5173 |
5167 | 5174 |
5168 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 5175 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { |
5169 Label* false_label, | 5176 Label* true_label = instr->TrueLabel(chunk_); |
5170 Register input, | 5177 Label* false_label = instr->FalseLabel(chunk_); |
5171 Handle<String> type_name) { | 5178 Handle<String> type_name = instr->type_literal(); |
| 5179 int left_block = instr->TrueDestination(chunk_); |
| 5180 int right_block = instr->FalseDestination(chunk_); |
| 5181 int next_block = GetNextEmittedBlock(); |
| 5182 |
| 5183 Label::Distance true_distance = Label::kFar; |
| 5184 Label::Distance false_distance = Label::kFar; |
| 5185 if (left_block == next_block) { |
| 5186 true_distance = Label::kNear; |
| 5187 } else if (right_block == next_block) { |
| 5188 false_distance = Label::kNear; |
| 5189 } |
| 5190 |
5172 Condition final_branch_condition = no_condition; | 5191 Condition final_branch_condition = no_condition; |
5173 if (type_name->Equals(heap()->number_string())) { | 5192 if (type_name->Equals(heap()->number_string())) { |
5174 __ JumpIfSmi(input, true_label); | 5193 __ JumpIfSmi(input, true_label, true_distance); |
5175 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), | 5194 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), |
5176 Heap::kHeapNumberMapRootIndex); | 5195 Heap::kHeapNumberMapRootIndex); |
5177 | 5196 |
5178 final_branch_condition = equal; | 5197 final_branch_condition = equal; |
5179 | 5198 |
5180 } else if (type_name->Equals(heap()->string_string())) { | 5199 } else if (type_name->Equals(heap()->string_string())) { |
5181 __ JumpIfSmi(input, false_label); | 5200 __ JumpIfSmi(input, false_label, false_distance); |
5182 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 5201 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
5183 __ j(above_equal, false_label); | 5202 __ j(above_equal, false_label, false_distance); |
5184 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5203 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5185 Immediate(1 << Map::kIsUndetectable)); | 5204 Immediate(1 << Map::kIsUndetectable)); |
5186 final_branch_condition = zero; | 5205 final_branch_condition = zero; |
5187 | 5206 |
5188 } else if (type_name->Equals(heap()->symbol_string())) { | 5207 } else if (type_name->Equals(heap()->symbol_string())) { |
5189 __ JumpIfSmi(input, false_label); | 5208 __ JumpIfSmi(input, false_label, false_distance); |
5190 __ CmpObjectType(input, SYMBOL_TYPE, input); | 5209 __ CmpObjectType(input, SYMBOL_TYPE, input); |
5191 final_branch_condition = equal; | 5210 final_branch_condition = equal; |
5192 | 5211 |
5193 } else if (type_name->Equals(heap()->boolean_string())) { | 5212 } else if (type_name->Equals(heap()->boolean_string())) { |
5194 __ CompareRoot(input, Heap::kTrueValueRootIndex); | 5213 __ CompareRoot(input, Heap::kTrueValueRootIndex); |
5195 __ j(equal, true_label); | 5214 __ j(equal, true_label, true_distance); |
5196 __ CompareRoot(input, Heap::kFalseValueRootIndex); | 5215 __ CompareRoot(input, Heap::kFalseValueRootIndex); |
5197 final_branch_condition = equal; | 5216 final_branch_condition = equal; |
5198 | 5217 |
5199 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { | 5218 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |
5200 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5219 __ CompareRoot(input, Heap::kNullValueRootIndex); |
5201 final_branch_condition = equal; | 5220 final_branch_condition = equal; |
5202 | 5221 |
5203 } else if (type_name->Equals(heap()->undefined_string())) { | 5222 } else if (type_name->Equals(heap()->undefined_string())) { |
5204 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); | 5223 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); |
5205 __ j(equal, true_label); | 5224 __ j(equal, true_label, true_distance); |
5206 __ JumpIfSmi(input, false_label); | 5225 __ JumpIfSmi(input, false_label, false_distance); |
5207 // Check for undetectable objects => true. | 5226 // Check for undetectable objects => true. |
5208 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); | 5227 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); |
5209 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5228 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5210 Immediate(1 << Map::kIsUndetectable)); | 5229 Immediate(1 << Map::kIsUndetectable)); |
5211 final_branch_condition = not_zero; | 5230 final_branch_condition = not_zero; |
5212 | 5231 |
5213 } else if (type_name->Equals(heap()->function_string())) { | 5232 } else if (type_name->Equals(heap()->function_string())) { |
5214 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 5233 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
5215 __ JumpIfSmi(input, false_label); | 5234 __ JumpIfSmi(input, false_label, false_distance); |
5216 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 5235 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |
5217 __ j(equal, true_label); | 5236 __ j(equal, true_label, true_distance); |
5218 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); | 5237 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); |
5219 final_branch_condition = equal; | 5238 final_branch_condition = equal; |
5220 | 5239 |
5221 } else if (type_name->Equals(heap()->object_string())) { | 5240 } else if (type_name->Equals(heap()->object_string())) { |
5222 __ JumpIfSmi(input, false_label); | 5241 __ JumpIfSmi(input, false_label, false_distance); |
5223 if (!FLAG_harmony_typeof) { | 5242 if (!FLAG_harmony_typeof) { |
5224 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5243 __ CompareRoot(input, Heap::kNullValueRootIndex); |
5225 __ j(equal, true_label); | 5244 __ j(equal, true_label, true_distance); |
5226 } | 5245 } |
5227 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 5246 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
5228 __ j(below, false_label); | 5247 __ j(below, false_label, false_distance); |
5229 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 5248 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
5230 __ j(above, false_label); | 5249 __ j(above, false_label, false_distance); |
5231 // Check for undetectable objects => false. | 5250 // Check for undetectable objects => false. |
5232 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5251 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5233 Immediate(1 << Map::kIsUndetectable)); | 5252 Immediate(1 << Map::kIsUndetectable)); |
5234 final_branch_condition = zero; | 5253 final_branch_condition = zero; |
5235 | 5254 |
5236 } else { | 5255 } else { |
5237 __ jmp(false_label); | 5256 __ jmp(false_label, false_distance); |
5238 } | 5257 } |
5239 | 5258 |
5240 return final_branch_condition; | 5259 return final_branch_condition; |
5241 } | 5260 } |
5242 | 5261 |
5243 | 5262 |
5244 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 5263 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
5245 Register temp = ToRegister(instr->temp()); | 5264 Register temp = ToRegister(instr->temp()); |
5246 | 5265 |
5247 EmitIsConstructCall(temp); | 5266 EmitIsConstructCall(temp); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5471 FixedArray::kHeaderSize - kPointerSize)); | 5490 FixedArray::kHeaderSize - kPointerSize)); |
5472 __ bind(&done); | 5491 __ bind(&done); |
5473 } | 5492 } |
5474 | 5493 |
5475 | 5494 |
5476 #undef __ | 5495 #undef __ |
5477 | 5496 |
5478 } } // namespace v8::internal | 5497 } } // namespace v8::internal |
5479 | 5498 |
5480 #endif // V8_TARGET_ARCH_X64 | 5499 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |