OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/crankshaft/lithium-codegen.h" | 5 #include "src/crankshaft/lithium-codegen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #if V8_TARGET_ARCH_IA32 | 9 #if V8_TARGET_ARCH_IA32 |
10 #include "src/crankshaft/ia32/lithium-ia32.h" // NOLINT | 10 #include "src/crankshaft/ia32/lithium-ia32.h" // NOLINT |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 Comment(";;; <@%d,#%d> %s", | 97 Comment(";;; <@%d,#%d> %s", |
98 current_instruction_, | 98 current_instruction_, |
99 instr->hydrogen_value()->id(), | 99 instr->hydrogen_value()->id(), |
100 instr->Mnemonic()); | 100 instr->Mnemonic()); |
101 } | 101 } |
102 | 102 |
103 GenerateBodyInstructionPre(instr); | 103 GenerateBodyInstructionPre(instr); |
104 | 104 |
105 HValue* value = instr->hydrogen_value(); | 105 HValue* value = instr->hydrogen_value(); |
106 if (!value->position().IsUnknown()) { | 106 if (!value->position().IsUnknown()) { |
107 RecordAndWritePosition( | 107 RecordAndWritePosition(value->position()); |
108 chunk()->graph()->SourcePositionToScriptPosition(value->position())); | |
109 } | 108 } |
110 | 109 |
111 instr->CompileToNative(codegen); | 110 instr->CompileToNative(codegen); |
112 | 111 |
113 GenerateBodyInstructionPost(instr); | 112 GenerateBodyInstructionPost(instr); |
114 } | 113 } |
115 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 114 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
116 last_lazy_deopt_pc_ = masm()->pc_offset(); | 115 last_lazy_deopt_pc_ = masm()->pc_offset(); |
117 return !is_aborted(); | 116 return !is_aborted(); |
118 } | 117 } |
(...skipping 15 matching lines...) Expand all Loading... |
134 } | 133 } |
135 | 134 |
136 if (instr->HasEnvironment() && !instr->environment()->has_been_used()) { | 135 if (instr->HasEnvironment() && !instr->environment()->has_been_used()) { |
137 V8_Fatal(__FILE__, __LINE__, "unused environment for %s (%s)", | 136 V8_Fatal(__FILE__, __LINE__, "unused environment for %s (%s)", |
138 hinstr->Mnemonic(), instr->Mnemonic()); | 137 hinstr->Mnemonic(), instr->Mnemonic()); |
139 } | 138 } |
140 } | 139 } |
141 #endif | 140 #endif |
142 } | 141 } |
143 | 142 |
144 void LCodeGenBase::RecordAndWritePosition(int pos) { | 143 void LCodeGenBase::RecordAndWritePosition(SourcePosition pos) { |
145 if (pos == kNoSourcePosition) return; | 144 if (pos.IsUnknown()) return; |
146 source_position_table_builder_.AddPosition(masm_->pc_offset(), pos, false); | 145 source_position_table_builder_.AddPosition(masm_->pc_offset(), pos, false); |
147 } | 146 } |
148 | 147 |
149 void LCodeGenBase::Comment(const char* format, ...) { | 148 void LCodeGenBase::Comment(const char* format, ...) { |
150 if (!FLAG_code_comments) return; | 149 if (!FLAG_code_comments) return; |
151 char buffer[4 * KB]; | 150 char buffer[4 * KB]; |
152 StringBuilder builder(buffer, arraysize(buffer)); | 151 StringBuilder builder(buffer, arraysize(buffer)); |
153 va_list arguments; | 152 va_list arguments; |
154 va_start(arguments, format); | 153 va_start(arguments, format); |
155 builder.AddFormattedList(format, arguments); | 154 builder.AddFormattedList(format, arguments); |
156 va_end(arguments); | 155 va_end(arguments); |
157 | 156 |
158 // Copy the string before recording it in the assembler to avoid | 157 // Copy the string before recording it in the assembler to avoid |
159 // issues when the stack allocated buffer goes out of scope. | 158 // issues when the stack allocated buffer goes out of scope. |
160 size_t length = builder.position(); | 159 size_t length = builder.position(); |
161 Vector<char> copy = Vector<char>::New(static_cast<int>(length) + 1); | 160 Vector<char> copy = Vector<char>::New(static_cast<int>(length) + 1); |
162 MemCopy(copy.start(), builder.Finalize(), copy.length()); | 161 MemCopy(copy.start(), builder.Finalize(), copy.length()); |
163 masm()->RecordComment(copy.start()); | 162 masm()->RecordComment(copy.start()); |
164 } | 163 } |
165 | 164 |
166 | 165 |
167 void LCodeGenBase::DeoptComment(const Deoptimizer::DeoptInfo& deopt_info) { | 166 void LCodeGenBase::DeoptComment(const Deoptimizer::DeoptInfo& deopt_info) { |
168 SourcePosition position = deopt_info.position; | 167 SourcePosition position = deopt_info.position; |
169 int deopt_id = deopt_info.deopt_id; | 168 int deopt_id = deopt_info.deopt_id; |
170 int raw_position = position.IsUnknown() ? 0 : position.raw(); | 169 masm()->RecordDeoptReason(deopt_info.deopt_reason, position, deopt_id); |
171 masm()->RecordDeoptReason(deopt_info.deopt_reason, raw_position, deopt_id); | |
172 } | 170 } |
173 | 171 |
174 | 172 |
175 int LCodeGenBase::GetNextEmittedBlock() const { | 173 int LCodeGenBase::GetNextEmittedBlock() const { |
176 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { | 174 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { |
177 if (!graph()->blocks()->at(i)->IsReachable()) continue; | 175 if (!graph()->blocks()->at(i)->IsReachable()) continue; |
178 if (!chunk_->GetLabel(i)->HasReplacement()) return i; | 176 if (!chunk_->GetLabel(i)->HasReplacement()) return i; |
179 } | 177 } |
180 return -1; | 178 return -1; |
181 } | 179 } |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 Handle<FixedArray> literals = | 333 Handle<FixedArray> literals = |
336 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 334 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
337 { | 335 { |
338 AllowDeferredHandleDereference copy_handles; | 336 AllowDeferredHandleDereference copy_handles; |
339 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 337 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
340 literals->set(i, *deoptimization_literals_[i]); | 338 literals->set(i, *deoptimization_literals_[i]); |
341 } | 339 } |
342 data->SetLiteralArray(*literals); | 340 data->SetLiteralArray(*literals); |
343 } | 341 } |
344 | 342 |
| 343 data->SetInliningPositions(*info_->CreateInliningPositions()); |
| 344 |
345 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 345 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
346 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 346 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
347 | 347 |
348 // Populate the deoptimization entries. | 348 // Populate the deoptimization entries. |
349 for (int i = 0; i < length; i++) { | 349 for (int i = 0; i < length; i++) { |
350 LEnvironment* env = deoptimizations_[i]; | 350 LEnvironment* env = deoptimizations_[i]; |
351 data->SetAstId(i, env->ast_id()); | 351 data->SetAstId(i, env->ast_id()); |
352 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 352 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
353 data->SetArgumentsStackHeight(i, | 353 data->SetArgumentsStackHeight(i, |
354 Smi::FromInt(env->arguments_stack_height())); | 354 Smi::FromInt(env->arguments_stack_height())); |
355 data->SetPc(i, Smi::FromInt(env->pc_offset())); | 355 data->SetPc(i, Smi::FromInt(env->pc_offset())); |
356 } | 356 } |
357 code->set_deoptimization_data(*data); | 357 code->set_deoptimization_data(*data); |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 void LCodeGenBase::PopulateDeoptimizationLiteralsWithInlinedFunctions() { | 361 void LCodeGenBase::PopulateDeoptimizationLiteralsWithInlinedFunctions() { |
362 DCHECK_EQ(0, deoptimization_literals_.length()); | 362 DCHECK_EQ(0, deoptimization_literals_.length()); |
363 for (Handle<SharedFunctionInfo> function : chunk()->inlined_functions()) { | 363 for (CompilationInfo::InlinedFunctionHolder& inlined : |
364 DefineDeoptimizationLiteral(function); | 364 info()->inlined_functions()) { |
| 365 if (!inlined.shared_info.is_identical_to(info()->shared_info())) { |
| 366 inlined.RegisterInlinedFunctionId(deoptimization_literals_.length()); |
| 367 DefineDeoptimizationLiteral(inlined.shared_info); |
| 368 } |
365 } | 369 } |
366 inlined_function_count_ = deoptimization_literals_.length(); | 370 inlined_function_count_ = deoptimization_literals_.length(); |
367 | 371 |
368 // Define deoptimization literals for all unoptimized code objects of inlined | 372 // Define deoptimization literals for all unoptimized code objects of inlined |
369 // functions. This ensures unoptimized code is kept alive by optimized code. | 373 // functions. This ensures unoptimized code is kept alive by optimized code. |
370 AllowDeferredHandleDereference allow_shared_function_info_dereference; | 374 for (const CompilationInfo::InlinedFunctionHolder& inlined : |
371 for (Handle<SharedFunctionInfo> function : chunk()->inlined_functions()) { | 375 info()->inlined_functions()) { |
372 DefineDeoptimizationLiteral(handle(function->code())); | 376 if (!inlined.shared_info.is_identical_to(info()->shared_info())) { |
| 377 DefineDeoptimizationLiteral(inlined.inlined_code_object_root); |
| 378 } |
373 } | 379 } |
374 } | 380 } |
375 | 381 |
376 Deoptimizer::DeoptInfo LCodeGenBase::MakeDeoptInfo( | 382 Deoptimizer::DeoptInfo LCodeGenBase::MakeDeoptInfo( |
377 LInstruction* instr, DeoptimizeReason deopt_reason, int deopt_id) { | 383 LInstruction* instr, DeoptimizeReason deopt_reason, int deopt_id) { |
378 Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(), | 384 Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(), |
379 deopt_reason, deopt_id); | 385 deopt_reason, deopt_id); |
380 return deopt_info; | 386 return deopt_info; |
381 } | 387 } |
382 | 388 |
383 } // namespace internal | 389 } // namespace internal |
384 } // namespace v8 | 390 } // namespace v8 |
OLD | NEW |