| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 GenerateDeferredCode() && | 77 GenerateDeferredCode() && |
| 78 GenerateDeoptJumpTable() && | 78 GenerateDeoptJumpTable() && |
| 79 GenerateSafepointTable(); | 79 GenerateSafepointTable(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 void LCodeGen::FinishCode(Handle<Code> code) { | 83 void LCodeGen::FinishCode(Handle<Code> code) { |
| 84 ASSERT(is_done()); | 84 ASSERT(is_done()); |
| 85 code->set_stack_slots(GetStackSlotCount()); | 85 code->set_stack_slots(GetStackSlotCount()); |
| 86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 87 if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code); | 87 RegisterDependentCodeForEmbeddedMaps(code); |
| 88 PopulateDeoptimizationData(code); | 88 PopulateDeoptimizationData(code); |
| 89 info()->CommitDependencies(code); | 89 info()->CommitDependencies(code); |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 void LChunkBuilder::Abort(BailoutReason reason) { | 93 void LChunkBuilder::Abort(BailoutReason reason) { |
| 94 info()->set_bailout_reason(reason); | 94 info()->set_bailout_reason(reason); |
| 95 status_ = ABORTED; | 95 status_ = ABORTED; |
| 96 } | 96 } |
| 97 | 97 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 | 260 |
| 261 | 261 |
| 262 bool LCodeGen::GenerateDeferredCode() { | 262 bool LCodeGen::GenerateDeferredCode() { |
| 263 ASSERT(is_generating()); | 263 ASSERT(is_generating()); |
| 264 if (deferred_.length() > 0) { | 264 if (deferred_.length() > 0) { |
| 265 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 265 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 266 LDeferredCode* code = deferred_[i]; | 266 LDeferredCode* code = deferred_[i]; |
| 267 | 267 |
| 268 HValue* value = | 268 HValue* value = |
| 269 instructions_->at(code->instruction_index())->hydrogen_value(); | 269 instructions_->at(code->instruction_index())->hydrogen_value(); |
| 270 RecordAndWritePosition( | 270 RecordAndWritePosition(value->position()); |
| 271 chunk()->graph()->SourcePositionToScriptPosition(value->position())); | |
| 272 | 271 |
| 273 Comment(";;; <@%d,#%d> " | 272 Comment(";;; <@%d,#%d> " |
| 274 "-------------------- Deferred %s --------------------", | 273 "-------------------- Deferred %s --------------------", |
| 275 code->instruction_index(), | 274 code->instruction_index(), |
| 276 code->instr()->hydrogen_value()->id(), | 275 code->instr()->hydrogen_value()->id(), |
| 277 code->instr()->Mnemonic()); | 276 code->instr()->Mnemonic()); |
| 278 __ bind(code->entry()); | 277 __ bind(code->entry()); |
| 279 if (NeedsDeferredFrame()) { | 278 if (NeedsDeferredFrame()) { |
| 280 Comment(";;; Build frame"); | 279 Comment(";;; Build frame"); |
| 281 ASSERT(!frame_is_built_); | 280 ASSERT(!frame_is_built_); |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 852 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 854 int length = deoptimizations_.length(); | 853 int length = deoptimizations_.length(); |
| 855 if (length == 0) return; | 854 if (length == 0) return; |
| 856 Handle<DeoptimizationInputData> data = | 855 Handle<DeoptimizationInputData> data = |
| 857 factory()->NewDeoptimizationInputData(length, TENURED); | 856 factory()->NewDeoptimizationInputData(length, TENURED); |
| 858 | 857 |
| 859 Handle<ByteArray> translations = | 858 Handle<ByteArray> translations = |
| 860 translations_.CreateByteArray(isolate()->factory()); | 859 translations_.CreateByteArray(isolate()->factory()); |
| 861 data->SetTranslationByteArray(*translations); | 860 data->SetTranslationByteArray(*translations); |
| 862 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 861 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
| 863 data->SetOptimizationId(Smi::FromInt(info_->optimization_id())); | |
| 864 | 862 |
| 865 Handle<FixedArray> literals = | 863 Handle<FixedArray> literals = |
| 866 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 864 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
| 867 { AllowDeferredHandleDereference copy_handles; | 865 { AllowDeferredHandleDereference copy_handles; |
| 868 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 866 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 869 literals->set(i, *deoptimization_literals_[i]); | 867 literals->set(i, *deoptimization_literals_[i]); |
| 870 } | 868 } |
| 871 data->SetLiteralArray(*literals); | 869 data->SetLiteralArray(*literals); |
| 872 } | 870 } |
| 873 | 871 |
| (...skipping 2915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3789 | 3787 |
| 3790 void LCodeGen::DoMathLog(LMathLog* instr) { | 3788 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 3791 __ PrepareCallCFunction(0, 1, scratch0()); | 3789 __ PrepareCallCFunction(0, 1, scratch0()); |
| 3792 __ MovToFloatParameter(ToDoubleRegister(instr->value())); | 3790 __ MovToFloatParameter(ToDoubleRegister(instr->value())); |
| 3793 __ CallCFunction(ExternalReference::math_log_double_function(isolate()), | 3791 __ CallCFunction(ExternalReference::math_log_double_function(isolate()), |
| 3794 0, 1); | 3792 0, 1); |
| 3795 __ MovFromFloatResult(ToDoubleRegister(instr->result())); | 3793 __ MovFromFloatResult(ToDoubleRegister(instr->result())); |
| 3796 } | 3794 } |
| 3797 | 3795 |
| 3798 | 3796 |
| 3799 void LCodeGen::DoMathClz32(LMathClz32* instr) { | |
| 3800 Register input = ToRegister(instr->value()); | |
| 3801 Register result = ToRegister(instr->result()); | |
| 3802 __ Clz(result, input); | |
| 3803 } | |
| 3804 | |
| 3805 | |
| 3806 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3797 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 3807 ASSERT(ToRegister(instr->context()).is(cp)); | 3798 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3808 ASSERT(ToRegister(instr->function()).is(a1)); | 3799 ASSERT(ToRegister(instr->function()).is(a1)); |
| 3809 ASSERT(instr->HasPointerMap()); | 3800 ASSERT(instr->HasPointerMap()); |
| 3810 | 3801 |
| 3811 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3802 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 3812 if (known_function.is_null()) { | 3803 if (known_function.is_null()) { |
| 3813 LPointerMap* pointers = instr->pointer_map(); | 3804 LPointerMap* pointers = instr->pointer_map(); |
| 3814 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3805 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3815 ParameterCount count(instr->arity()); | 3806 ParameterCount count(instr->arity()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3969 int offset = access.offset(); | 3960 int offset = access.offset(); |
| 3970 | 3961 |
| 3971 if (access.IsExternalMemory()) { | 3962 if (access.IsExternalMemory()) { |
| 3972 Register value = ToRegister(instr->value()); | 3963 Register value = ToRegister(instr->value()); |
| 3973 MemOperand operand = MemOperand(object, offset); | 3964 MemOperand operand = MemOperand(object, offset); |
| 3974 __ Store(value, operand, representation); | 3965 __ Store(value, operand, representation); |
| 3975 return; | 3966 return; |
| 3976 } | 3967 } |
| 3977 | 3968 |
| 3978 Handle<Map> transition = instr->transition(); | 3969 Handle<Map> transition = instr->transition(); |
| 3979 SmiCheck check_needed = | |
| 3980 instr->hydrogen()->value()->IsHeapObject() | |
| 3981 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
| 3982 | 3970 |
| 3983 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 3971 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 3984 Register value = ToRegister(instr->value()); | 3972 Register value = ToRegister(instr->value()); |
| 3985 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 3973 if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
| 3986 __ SmiTst(value, scratch); | 3974 __ SmiTst(value, scratch); |
| 3987 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); | 3975 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); |
| 3988 | |
| 3989 // We know that value is a smi now, so we can omit the check below. | |
| 3990 check_needed = OMIT_SMI_CHECK; | |
| 3991 } | 3976 } |
| 3992 } else if (representation.IsDouble()) { | 3977 } else if (representation.IsDouble()) { |
| 3993 ASSERT(transition.is_null()); | 3978 ASSERT(transition.is_null()); |
| 3994 ASSERT(access.IsInobject()); | 3979 ASSERT(access.IsInobject()); |
| 3995 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3980 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 3996 DoubleRegister value = ToDoubleRegister(instr->value()); | 3981 DoubleRegister value = ToDoubleRegister(instr->value()); |
| 3997 __ sdc1(value, FieldMemOperand(object, offset)); | 3982 __ sdc1(value, FieldMemOperand(object, offset)); |
| 3998 return; | 3983 return; |
| 3999 } | 3984 } |
| 4000 | 3985 |
| 4001 if (!transition.is_null()) { | 3986 if (!transition.is_null()) { |
| 4002 __ li(scratch, Operand(transition)); | 3987 __ li(scratch, Operand(transition)); |
| 4003 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); | 3988 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 4004 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { | 3989 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { |
| 4005 Register temp = ToRegister(instr->temp()); | 3990 Register temp = ToRegister(instr->temp()); |
| 4006 // Update the write barrier for the map field. | 3991 // Update the write barrier for the map field. |
| 4007 __ RecordWriteField(object, | 3992 __ RecordWriteField(object, |
| 4008 HeapObject::kMapOffset, | 3993 HeapObject::kMapOffset, |
| 4009 scratch, | 3994 scratch, |
| 4010 temp, | 3995 temp, |
| 4011 GetRAState(), | 3996 GetRAState(), |
| 4012 kSaveFPRegs, | 3997 kSaveFPRegs, |
| 4013 OMIT_REMEMBERED_SET, | 3998 OMIT_REMEMBERED_SET, |
| 4014 OMIT_SMI_CHECK); | 3999 OMIT_SMI_CHECK); |
| 4015 } | 4000 } |
| 4016 } | 4001 } |
| 4017 | 4002 |
| 4018 // Do the store. | 4003 // Do the store. |
| 4019 Register value = ToRegister(instr->value()); | 4004 Register value = ToRegister(instr->value()); |
| 4005 SmiCheck check_needed = |
| 4006 instr->hydrogen()->value()->IsHeapObject() |
| 4007 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4020 if (access.IsInobject()) { | 4008 if (access.IsInobject()) { |
| 4021 MemOperand operand = FieldMemOperand(object, offset); | 4009 MemOperand operand = FieldMemOperand(object, offset); |
| 4022 __ Store(value, operand, representation); | 4010 __ Store(value, operand, representation); |
| 4023 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4011 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4024 // Update the write barrier for the object for in-object properties. | 4012 // Update the write barrier for the object for in-object properties. |
| 4025 __ RecordWriteField(object, | 4013 __ RecordWriteField(object, |
| 4026 offset, | 4014 offset, |
| 4027 value, | 4015 value, |
| 4028 scratch, | 4016 scratch, |
| 4029 GetRAState(), | 4017 GetRAState(), |
| (...skipping 1712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5742 __ Subu(scratch, result, scratch); | 5730 __ Subu(scratch, result, scratch); |
| 5743 __ lw(result, FieldMemOperand(scratch, | 5731 __ lw(result, FieldMemOperand(scratch, |
| 5744 FixedArray::kHeaderSize - kPointerSize)); | 5732 FixedArray::kHeaderSize - kPointerSize)); |
| 5745 __ bind(&done); | 5733 __ bind(&done); |
| 5746 } | 5734 } |
| 5747 | 5735 |
| 5748 | 5736 |
| 5749 #undef __ | 5737 #undef __ |
| 5750 | 5738 |
| 5751 } } // namespace v8::internal | 5739 } } // namespace v8::internal |
| OLD | NEW |