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 5330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5341 } else if (operand->IsRegister()) { | 5341 } else if (operand->IsRegister()) { |
5342 __ push(ToRegister(operand)); | 5342 __ push(ToRegister(operand)); |
5343 } else { | 5343 } else { |
5344 __ push(ToOperand(operand)); | 5344 __ push(ToOperand(operand)); |
5345 } | 5345 } |
5346 } | 5346 } |
5347 | 5347 |
5348 | 5348 |
5349 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 5349 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
5350 Register input = ToRegister(instr->value()); | 5350 Register input = ToRegister(instr->value()); |
5351 | 5351 Condition final_branch_condition = EmitTypeofIs(instr, input); |
5352 Condition final_branch_condition = | |
5353 EmitTypeofIs(instr->TrueLabel(chunk_), | |
5354 instr->FalseLabel(chunk_), input, instr->type_literal()); | |
5355 if (final_branch_condition != no_condition) { | 5352 if (final_branch_condition != no_condition) { |
5356 EmitBranch(instr, final_branch_condition); | 5353 EmitBranch(instr, final_branch_condition); |
5357 } | 5354 } |
5358 } | 5355 } |
5359 | 5356 |
5360 | 5357 |
5361 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 5358 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { |
5362 Label* false_label, | 5359 Label* true_label = instr->TrueLabel(chunk_); |
5363 Register input, | 5360 Label* false_label = instr->FalseLabel(chunk_); |
5364 Handle<String> type_name) { | 5361 Handle<String> type_name = instr->type_literal(); |
| 5362 int left_block = instr->TrueDestination(chunk_); |
| 5363 int right_block = instr->FalseDestination(chunk_); |
| 5364 int next_block = GetNextEmittedBlock(); |
| 5365 |
| 5366 Label::Distance true_distance = left_block == next_block ? Label::kNear |
| 5367 : Label::kFar; |
| 5368 Label::Distance false_distance = right_block == next_block ? Label::kNear |
| 5369 : Label::kFar; |
5365 Condition final_branch_condition = no_condition; | 5370 Condition final_branch_condition = no_condition; |
5366 if (type_name->Equals(heap()->number_string())) { | 5371 if (type_name->Equals(heap()->number_string())) { |
5367 __ JumpIfSmi(input, true_label); | 5372 __ JumpIfSmi(input, true_label, true_distance); |
5368 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), | 5373 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), |
5369 Heap::kHeapNumberMapRootIndex); | 5374 Heap::kHeapNumberMapRootIndex); |
5370 | 5375 |
5371 final_branch_condition = equal; | 5376 final_branch_condition = equal; |
5372 | 5377 |
5373 } else if (type_name->Equals(heap()->string_string())) { | 5378 } else if (type_name->Equals(heap()->string_string())) { |
5374 __ JumpIfSmi(input, false_label); | 5379 __ JumpIfSmi(input, false_label, false_distance); |
5375 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 5380 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
5376 __ j(above_equal, false_label); | 5381 __ j(above_equal, false_label, false_distance); |
5377 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5382 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5378 Immediate(1 << Map::kIsUndetectable)); | 5383 Immediate(1 << Map::kIsUndetectable)); |
5379 final_branch_condition = zero; | 5384 final_branch_condition = zero; |
5380 | 5385 |
5381 } else if (type_name->Equals(heap()->symbol_string())) { | 5386 } else if (type_name->Equals(heap()->symbol_string())) { |
5382 __ JumpIfSmi(input, false_label); | 5387 __ JumpIfSmi(input, false_label, false_distance); |
5383 __ CmpObjectType(input, SYMBOL_TYPE, input); | 5388 __ CmpObjectType(input, SYMBOL_TYPE, input); |
5384 final_branch_condition = equal; | 5389 final_branch_condition = equal; |
5385 | 5390 |
5386 } else if (type_name->Equals(heap()->boolean_string())) { | 5391 } else if (type_name->Equals(heap()->boolean_string())) { |
5387 __ CompareRoot(input, Heap::kTrueValueRootIndex); | 5392 __ CompareRoot(input, Heap::kTrueValueRootIndex); |
5388 __ j(equal, true_label); | 5393 __ j(equal, true_label, true_distance); |
5389 __ CompareRoot(input, Heap::kFalseValueRootIndex); | 5394 __ CompareRoot(input, Heap::kFalseValueRootIndex); |
5390 final_branch_condition = equal; | 5395 final_branch_condition = equal; |
5391 | 5396 |
5392 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { | 5397 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |
5393 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5398 __ CompareRoot(input, Heap::kNullValueRootIndex); |
5394 final_branch_condition = equal; | 5399 final_branch_condition = equal; |
5395 | 5400 |
5396 } else if (type_name->Equals(heap()->undefined_string())) { | 5401 } else if (type_name->Equals(heap()->undefined_string())) { |
5397 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); | 5402 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); |
5398 __ j(equal, true_label); | 5403 __ j(equal, true_label, true_distance); |
5399 __ JumpIfSmi(input, false_label); | 5404 __ JumpIfSmi(input, false_label, false_distance); |
5400 // Check for undetectable objects => true. | 5405 // Check for undetectable objects => true. |
5401 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); | 5406 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); |
5402 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5407 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5403 Immediate(1 << Map::kIsUndetectable)); | 5408 Immediate(1 << Map::kIsUndetectable)); |
5404 final_branch_condition = not_zero; | 5409 final_branch_condition = not_zero; |
5405 | 5410 |
5406 } else if (type_name->Equals(heap()->function_string())) { | 5411 } else if (type_name->Equals(heap()->function_string())) { |
5407 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 5412 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
5408 __ JumpIfSmi(input, false_label); | 5413 __ JumpIfSmi(input, false_label, false_distance); |
5409 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 5414 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |
5410 __ j(equal, true_label); | 5415 __ j(equal, true_label, true_distance); |
5411 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); | 5416 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); |
5412 final_branch_condition = equal; | 5417 final_branch_condition = equal; |
5413 | 5418 |
5414 } else if (type_name->Equals(heap()->object_string())) { | 5419 } else if (type_name->Equals(heap()->object_string())) { |
5415 __ JumpIfSmi(input, false_label); | 5420 __ JumpIfSmi(input, false_label, false_distance); |
5416 if (!FLAG_harmony_typeof) { | 5421 if (!FLAG_harmony_typeof) { |
5417 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5422 __ CompareRoot(input, Heap::kNullValueRootIndex); |
5418 __ j(equal, true_label); | 5423 __ j(equal, true_label, true_distance); |
5419 } | 5424 } |
5420 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 5425 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
5421 __ j(below, false_label); | 5426 __ j(below, false_label, false_distance); |
5422 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 5427 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
5423 __ j(above, false_label); | 5428 __ j(above, false_label, false_distance); |
5424 // Check for undetectable objects => false. | 5429 // Check for undetectable objects => false. |
5425 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5430 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5426 Immediate(1 << Map::kIsUndetectable)); | 5431 Immediate(1 << Map::kIsUndetectable)); |
5427 final_branch_condition = zero; | 5432 final_branch_condition = zero; |
5428 | 5433 |
5429 } else { | 5434 } else { |
5430 __ jmp(false_label); | 5435 __ jmp(false_label, false_distance); |
5431 } | 5436 } |
5432 | 5437 |
5433 return final_branch_condition; | 5438 return final_branch_condition; |
5434 } | 5439 } |
5435 | 5440 |
5436 | 5441 |
5437 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 5442 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
5438 Register temp = ToRegister(instr->temp()); | 5443 Register temp = ToRegister(instr->temp()); |
5439 | 5444 |
5440 EmitIsConstructCall(temp); | 5445 EmitIsConstructCall(temp); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5673 FixedArray::kHeaderSize - kPointerSize)); | 5678 FixedArray::kHeaderSize - kPointerSize)); |
5674 __ bind(&done); | 5679 __ bind(&done); |
5675 } | 5680 } |
5676 | 5681 |
5677 | 5682 |
5678 #undef __ | 5683 #undef __ |
5679 | 5684 |
5680 } } // namespace v8::internal | 5685 } } // namespace v8::internal |
5681 | 5686 |
5682 #endif // V8_TARGET_ARCH_X64 | 5687 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |