Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Side by Side Diff: src/compiler/code-generator.cc

Issue 573703002: Add handling for deopt and argument adaptor frames. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: mstarzinger's comments Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/code-generator.h ('k') | src/compiler/common-operator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/linkage.h" 8 #include "src/compiler/linkage.h"
9 #include "src/compiler/pipeline.h" 9 #include "src/compiler/pipeline.h"
10 10
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 239
240 if (flags & CallDescriptor::kNeedsNopAfterCall) { 240 if (flags & CallDescriptor::kNeedsNopAfterCall) {
241 AddNopForSmiCodeInlining(); 241 AddNopForSmiCodeInlining();
242 } 242 }
243 243
244 if (needs_frame_state) { 244 if (needs_frame_state) {
245 // If the frame state is present, it starts at argument 1 245 // If the frame state is present, it starts at argument 1
246 // (just after the code address). 246 // (just after the code address).
247 InstructionOperandConverter converter(this, instr); 247 InstructionOperandConverter converter(this, instr);
248 // Deoptimization info starts at argument 1 248 // Deoptimization info starts at argument 1
249 int frame_state_offset = 1; 249 size_t frame_state_offset = 1;
250 FrameStateDescriptor* descriptor = 250 FrameStateDescriptor* descriptor =
251 GetFrameStateDescriptor(instr, frame_state_offset); 251 GetFrameStateDescriptor(instr, frame_state_offset);
252 int pc_offset = masm()->pc_offset(); 252 int pc_offset = masm()->pc_offset();
253 int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, 253 int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset,
254 descriptor->state_combine()); 254 descriptor->state_combine());
255 // If the pre-call frame state differs from the post-call one, produce the 255 // If the pre-call frame state differs from the post-call one, produce the
256 // pre-call frame state, too. 256 // pre-call frame state, too.
257 // TODO(jarin) We might want to avoid building the pre-call frame state 257 // TODO(jarin) We might want to avoid building the pre-call frame state
258 // because it is only used to get locals and arguments (by the debugger and 258 // because it is only used to get locals and arguments (by the debugger and
259 // f.arguments), and those are the same in the pre-call and post-call 259 // f.arguments), and those are the same in the pre-call and post-call
260 // states. 260 // states.
261 if (descriptor->state_combine() != kIgnoreOutput) { 261 if (descriptor->state_combine() != kIgnoreOutput) {
262 deopt_state_id = 262 deopt_state_id =
263 BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput); 263 BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput);
264 } 264 }
265 #if DEBUG 265 #if DEBUG
266 // Make sure all the values live in stack slots or they are immediates. 266 // Make sure all the values live in stack slots or they are immediates.
267 // (The values should not live in register because registers are clobbered 267 // (The values should not live in register because registers are clobbered
268 // by calls.) 268 // by calls.)
269 for (int i = 0; i < descriptor->size(); i++) { 269 for (size_t i = 0; i < descriptor->size(); i++) {
270 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); 270 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i);
271 CHECK(op->IsStackSlot() || op->IsImmediate()); 271 CHECK(op->IsStackSlot() || op->IsImmediate());
272 } 272 }
273 #endif 273 #endif
274 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); 274 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id);
275 } 275 }
276 } 276 }
277 277
278 278
279 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { 279 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) {
280 int result = static_cast<int>(deoptimization_literals_.size()); 280 int result = static_cast<int>(deoptimization_literals_.size());
281 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { 281 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) {
282 if (deoptimization_literals_[i].is_identical_to(literal)) return i; 282 if (deoptimization_literals_[i].is_identical_to(literal)) return i;
283 } 283 }
284 deoptimization_literals_.push_back(literal); 284 deoptimization_literals_.push_back(literal);
285 return result; 285 return result;
286 } 286 }
287 287
288 288
289 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( 289 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor(
290 Instruction* instr, int frame_state_offset) { 290 Instruction* instr, size_t frame_state_offset) {
291 InstructionOperandConverter i(this, instr); 291 InstructionOperandConverter i(this, instr);
292 InstructionSequence::StateId state_id = 292 InstructionSequence::StateId state_id = InstructionSequence::StateId::FromInt(
293 InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); 293 i.InputInt32(static_cast<int>(frame_state_offset)));
294 return code()->GetFrameStateDescriptor(state_id); 294 return code()->GetFrameStateDescriptor(state_id);
295 } 295 }
296 296
297 297
298 void CodeGenerator::BuildTranslationForFrameStateDescriptor( 298 void CodeGenerator::BuildTranslationForFrameStateDescriptor(
299 FrameStateDescriptor* descriptor, Instruction* instr, 299 FrameStateDescriptor* descriptor, Instruction* instr,
300 Translation* translation, int frame_state_offset, 300 Translation* translation, size_t frame_state_offset,
301 OutputFrameStateCombine state_combine) { 301 OutputFrameStateCombine state_combine) {
302 // Outer-most state must be added to translation first. 302 // Outer-most state must be added to translation first.
303 if (descriptor->outer_state() != NULL) { 303 if (descriptor->outer_state() != NULL) {
304 BuildTranslationForFrameStateDescriptor( 304 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr,
305 descriptor->outer_state(), instr, translation, 305 translation, frame_state_offset,
306 frame_state_offset + descriptor->size(), kIgnoreOutput); 306 kIgnoreOutput);
307 } 307 }
308 308
309 int height = descriptor->size() - descriptor->parameters_count(); 309 int id = Translation::kSelfLiteralId;
310 switch (state_combine) { 310 if (!descriptor->jsfunction().is_null()) {
311 case kPushOutput: 311 id = DefineDeoptimizationLiteral(
312 height++; 312 Handle<Object>::cast(descriptor->jsfunction().ToHandleChecked()));
313 }
314
315 switch (descriptor->type()) {
316 case JS_FRAME:
317 translation->BeginJSFrame(
318 descriptor->bailout_id(), id,
319 static_cast<unsigned int>(descriptor->GetHeight(state_combine)));
313 break; 320 break;
314 case kIgnoreOutput: 321 case ARGUMENTS_ADAPTOR:
322 translation->BeginArgumentsAdaptorFrame(
323 id, static_cast<unsigned int>(descriptor->parameters_count()));
315 break; 324 break;
316 } 325 }
317 326
318 translation->BeginJSFrame(descriptor->bailout_id(), 327 frame_state_offset += descriptor->outer_state()->GetTotalSize();
319 Translation::kSelfLiteralId, height); 328 for (size_t i = 0; i < descriptor->size(); i++) {
320 329 AddTranslationForOperand(
321 for (int i = 0; i < descriptor->size(); i++) { 330 translation, instr,
322 AddTranslationForOperand(translation, instr, 331 instr->InputAt(static_cast<int>(frame_state_offset + i)));
323 instr->InputAt(i + frame_state_offset));
324 } 332 }
325 333
326 switch (state_combine) { 334 switch (state_combine) {
327 case kPushOutput: 335 case kPushOutput:
328 DCHECK(instr->OutputCount() == 1); 336 DCHECK(instr->OutputCount() == 1);
329 AddTranslationForOperand(translation, instr, instr->OutputAt(0)); 337 AddTranslationForOperand(translation, instr, instr->OutputAt(0));
330 break; 338 break;
331 case kIgnoreOutput: 339 case kIgnoreOutput:
332 break; 340 break;
333 } 341 }
334 } 342 }
335 343
336 344
337 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, 345 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset,
338 int frame_state_offset, 346 size_t frame_state_offset,
339 OutputFrameStateCombine state_combine) { 347 OutputFrameStateCombine state_combine) {
340 FrameStateDescriptor* descriptor = 348 FrameStateDescriptor* descriptor =
341 GetFrameStateDescriptor(instr, frame_state_offset); 349 GetFrameStateDescriptor(instr, frame_state_offset);
342 frame_state_offset++; 350 frame_state_offset++;
343 351
344 int frame_count = descriptor->GetFrameCount(); 352 Translation translation(
345 Translation translation(&translations_, frame_count, frame_count, zone()); 353 &translations_, static_cast<int>(descriptor->GetFrameCount()),
354 static_cast<int>(descriptor->GetJSFrameCount()), zone());
346 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, 355 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation,
347 frame_state_offset, state_combine); 356 frame_state_offset, state_combine);
348 357
349 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); 358 int deoptimization_id = static_cast<int>(deoptimization_states_.size());
350 359
351 deoptimization_states_.push_back(new (zone()) DeoptimizationState( 360 deoptimization_states_.push_back(new (zone()) DeoptimizationState(
352 descriptor->bailout_id(), translation.index(), pc_offset)); 361 descriptor->bailout_id(), translation.index(), pc_offset));
353 362
354 return deoptimization_id; 363 return deoptimization_id;
355 } 364 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 } 445 }
437 446
438 447
439 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } 448 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); }
440 449
441 #endif // !V8_TURBOFAN_BACKEND 450 #endif // !V8_TURBOFAN_BACKEND
442 451
443 } // namespace compiler 452 } // namespace compiler
444 } // namespace internal 453 } // namespace internal
445 } // namespace v8 454 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/code-generator.h ('k') | src/compiler/common-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698