| OLD | NEW |
| 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 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 __ j(cc, &jump_table_.last().label); | 546 __ j(cc, &jump_table_.last().label); |
| 547 } | 547 } |
| 548 } | 548 } |
| 549 | 549 |
| 550 | 550 |
| 551 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 551 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 552 int length = deoptimizations_.length(); | 552 int length = deoptimizations_.length(); |
| 553 if (length == 0) return; | 553 if (length == 0) return; |
| 554 ASSERT(FLAG_deopt); | 554 ASSERT(FLAG_deopt); |
| 555 Handle<DeoptimizationInputData> data = | 555 Handle<DeoptimizationInputData> data = |
| 556 FACTORY->NewDeoptimizationInputData(length, TENURED); | 556 factory()->NewDeoptimizationInputData(length, TENURED); |
| 557 | 557 |
| 558 Handle<ByteArray> translations = translations_.CreateByteArray(); | 558 Handle<ByteArray> translations = translations_.CreateByteArray(); |
| 559 data->SetTranslationByteArray(*translations); | 559 data->SetTranslationByteArray(*translations); |
| 560 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 560 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
| 561 | 561 |
| 562 Handle<FixedArray> literals = | 562 Handle<FixedArray> literals = |
| 563 FACTORY->NewFixedArray(deoptimization_literals_.length(), TENURED); | 563 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
| 564 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 564 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 565 literals->set(i, *deoptimization_literals_[i]); | 565 literals->set(i, *deoptimization_literals_[i]); |
| 566 } | 566 } |
| 567 data->SetLiteralArray(*literals); | 567 data->SetLiteralArray(*literals); |
| 568 | 568 |
| 569 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id())); | 569 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id())); |
| 570 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 570 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
| 571 | 571 |
| 572 // Populate the deoptimization entries. | 572 // Populate the deoptimization entries. |
| 573 for (int i = 0; i < length; i++) { | 573 for (int i = 0; i < length; i++) { |
| (...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 __ JumpIfSmi(object, &false_result); | 1863 __ JumpIfSmi(object, &false_result); |
| 1864 | 1864 |
| 1865 // This is the inlined call site instanceof cache. The two occurences of the | 1865 // This is the inlined call site instanceof cache. The two occurences of the |
| 1866 // hole value will be patched to the last map/result pair generated by the | 1866 // hole value will be patched to the last map/result pair generated by the |
| 1867 // instanceof stub. | 1867 // instanceof stub. |
| 1868 NearLabel cache_miss; | 1868 NearLabel cache_miss; |
| 1869 // Use a temp register to avoid memory operands with variable lengths. | 1869 // Use a temp register to avoid memory operands with variable lengths. |
| 1870 Register map = ToRegister(instr->TempAt(0)); | 1870 Register map = ToRegister(instr->TempAt(0)); |
| 1871 __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); | 1871 __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); |
| 1872 __ bind(deferred->map_check()); // Label for calculating code patching. | 1872 __ bind(deferred->map_check()); // Label for calculating code patching. |
| 1873 __ Move(kScratchRegister, FACTORY->the_hole_value()); | 1873 __ Move(kScratchRegister, factory()->the_hole_value()); |
| 1874 __ cmpq(map, kScratchRegister); // Patched to cached map. | 1874 __ cmpq(map, kScratchRegister); // Patched to cached map. |
| 1875 __ j(not_equal, &cache_miss); | 1875 __ j(not_equal, &cache_miss); |
| 1876 // Patched to load either true or false. | 1876 // Patched to load either true or false. |
| 1877 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); | 1877 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); |
| 1878 #ifdef DEBUG | 1878 #ifdef DEBUG |
| 1879 // Check that the code size between patch label and patch sites is invariant. | 1879 // Check that the code size between patch label and patch sites is invariant. |
| 1880 Label end_of_patched_code; | 1880 Label end_of_patched_code; |
| 1881 __ bind(&end_of_patched_code); | 1881 __ bind(&end_of_patched_code); |
| 1882 ASSERT(true); | 1882 ASSERT(true); |
| 1883 #endif | 1883 #endif |
| (...skipping 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3354 LOperand* input = instr->InputAt(0); | 3354 LOperand* input = instr->InputAt(0); |
| 3355 ASSERT(input->IsRegister()); | 3355 ASSERT(input->IsRegister()); |
| 3356 Register reg = ToRegister(input); | 3356 Register reg = ToRegister(input); |
| 3357 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3357 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 3358 instr->hydrogen()->map()); | 3358 instr->hydrogen()->map()); |
| 3359 DeoptimizeIf(not_equal, instr->environment()); | 3359 DeoptimizeIf(not_equal, instr->environment()); |
| 3360 } | 3360 } |
| 3361 | 3361 |
| 3362 | 3362 |
| 3363 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | 3363 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { |
| 3364 if (HEAP->InNewSpace(*object)) { | 3364 if (heap()->InNewSpace(*object)) { |
| 3365 Handle<JSGlobalPropertyCell> cell = | 3365 Handle<JSGlobalPropertyCell> cell = |
| 3366 FACTORY->NewJSGlobalPropertyCell(object); | 3366 factory()->NewJSGlobalPropertyCell(object); |
| 3367 __ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL); | 3367 __ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL); |
| 3368 __ movq(result, Operand(result, 0)); | 3368 __ movq(result, Operand(result, 0)); |
| 3369 } else { | 3369 } else { |
| 3370 __ Move(result, object); | 3370 __ Move(result, object); |
| 3371 } | 3371 } |
| 3372 } | 3372 } |
| 3373 | 3373 |
| 3374 | 3374 |
| 3375 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 3375 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
| 3376 Register reg = ToRegister(instr->TempAt(0)); | 3376 Register reg = ToRegister(instr->TempAt(0)); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3584 | 3584 |
| 3585 EmitBranch(true_block, false_block, final_branch_condition); | 3585 EmitBranch(true_block, false_block, final_branch_condition); |
| 3586 } | 3586 } |
| 3587 | 3587 |
| 3588 | 3588 |
| 3589 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 3589 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
| 3590 Label* false_label, | 3590 Label* false_label, |
| 3591 Register input, | 3591 Register input, |
| 3592 Handle<String> type_name) { | 3592 Handle<String> type_name) { |
| 3593 Condition final_branch_condition = no_condition; | 3593 Condition final_branch_condition = no_condition; |
| 3594 if (type_name->Equals(HEAP->number_symbol())) { | 3594 if (type_name->Equals(heap()->number_symbol())) { |
| 3595 __ JumpIfSmi(input, true_label); | 3595 __ JumpIfSmi(input, true_label); |
| 3596 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), | 3596 __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), |
| 3597 Heap::kHeapNumberMapRootIndex); | 3597 Heap::kHeapNumberMapRootIndex); |
| 3598 | 3598 |
| 3599 final_branch_condition = equal; | 3599 final_branch_condition = equal; |
| 3600 | 3600 |
| 3601 } else if (type_name->Equals(HEAP->string_symbol())) { | 3601 } else if (type_name->Equals(heap()->string_symbol())) { |
| 3602 __ JumpIfSmi(input, false_label); | 3602 __ JumpIfSmi(input, false_label); |
| 3603 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 3603 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
| 3604 __ j(above_equal, false_label); | 3604 __ j(above_equal, false_label); |
| 3605 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 3605 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
| 3606 Immediate(1 << Map::kIsUndetectable)); | 3606 Immediate(1 << Map::kIsUndetectable)); |
| 3607 final_branch_condition = zero; | 3607 final_branch_condition = zero; |
| 3608 | 3608 |
| 3609 } else if (type_name->Equals(HEAP->boolean_symbol())) { | 3609 } else if (type_name->Equals(heap()->boolean_symbol())) { |
| 3610 __ CompareRoot(input, Heap::kTrueValueRootIndex); | 3610 __ CompareRoot(input, Heap::kTrueValueRootIndex); |
| 3611 __ j(equal, true_label); | 3611 __ j(equal, true_label); |
| 3612 __ CompareRoot(input, Heap::kFalseValueRootIndex); | 3612 __ CompareRoot(input, Heap::kFalseValueRootIndex); |
| 3613 final_branch_condition = equal; | 3613 final_branch_condition = equal; |
| 3614 | 3614 |
| 3615 } else if (type_name->Equals(HEAP->undefined_symbol())) { | 3615 } else if (type_name->Equals(heap()->undefined_symbol())) { |
| 3616 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); | 3616 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); |
| 3617 __ j(equal, true_label); | 3617 __ j(equal, true_label); |
| 3618 __ JumpIfSmi(input, false_label); | 3618 __ JumpIfSmi(input, false_label); |
| 3619 // Check for undetectable objects => true. | 3619 // Check for undetectable objects => true. |
| 3620 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); | 3620 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); |
| 3621 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 3621 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
| 3622 Immediate(1 << Map::kIsUndetectable)); | 3622 Immediate(1 << Map::kIsUndetectable)); |
| 3623 final_branch_condition = not_zero; | 3623 final_branch_condition = not_zero; |
| 3624 | 3624 |
| 3625 } else if (type_name->Equals(HEAP->function_symbol())) { | 3625 } else if (type_name->Equals(heap()->function_symbol())) { |
| 3626 __ JumpIfSmi(input, false_label); | 3626 __ JumpIfSmi(input, false_label); |
| 3627 __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input); | 3627 __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input); |
| 3628 final_branch_condition = above_equal; | 3628 final_branch_condition = above_equal; |
| 3629 | 3629 |
| 3630 } else if (type_name->Equals(HEAP->object_symbol())) { | 3630 } else if (type_name->Equals(heap()->object_symbol())) { |
| 3631 __ JumpIfSmi(input, false_label); | 3631 __ JumpIfSmi(input, false_label); |
| 3632 __ CompareRoot(input, Heap::kNullValueRootIndex); | 3632 __ CompareRoot(input, Heap::kNullValueRootIndex); |
| 3633 __ j(equal, true_label); | 3633 __ j(equal, true_label); |
| 3634 __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input); | 3634 __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input); |
| 3635 __ j(below, false_label); | 3635 __ j(below, false_label); |
| 3636 __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); | 3636 __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); |
| 3637 __ j(above_equal, false_label); | 3637 __ j(above_equal, false_label); |
| 3638 // Check for undetectable objects => false. | 3638 // Check for undetectable objects => false. |
| 3639 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 3639 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
| 3640 Immediate(1 << Map::kIsUndetectable)); | 3640 Immediate(1 << Map::kIsUndetectable)); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3768 RegisterEnvironmentForDeoptimization(environment); | 3768 RegisterEnvironmentForDeoptimization(environment); |
| 3769 ASSERT(osr_pc_offset_ == -1); | 3769 ASSERT(osr_pc_offset_ == -1); |
| 3770 osr_pc_offset_ = masm()->pc_offset(); | 3770 osr_pc_offset_ = masm()->pc_offset(); |
| 3771 } | 3771 } |
| 3772 | 3772 |
| 3773 #undef __ | 3773 #undef __ |
| 3774 | 3774 |
| 3775 } } // namespace v8::internal | 3775 } } // namespace v8::internal |
| 3776 | 3776 |
| 3777 #endif // V8_TARGET_ARCH_X64 | 3777 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |