OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 | 346 |
347 unsigned FullCodeGenerator::EmitStackCheckTable() { | 347 unsigned FullCodeGenerator::EmitStackCheckTable() { |
348 // The stack check table consists of a length (in number of entries) | 348 // The stack check table consists of a length (in number of entries) |
349 // field, and then a sequence of entries. Each entry is a pair of AST id | 349 // field, and then a sequence of entries. Each entry is a pair of AST id |
350 // and code-relative pc offset. | 350 // and code-relative pc offset. |
351 masm()->Align(kIntSize); | 351 masm()->Align(kIntSize); |
352 unsigned offset = masm()->pc_offset(); | 352 unsigned offset = masm()->pc_offset(); |
353 unsigned length = stack_checks_.length(); | 353 unsigned length = stack_checks_.length(); |
354 __ dd(length); | 354 __ dd(length); |
355 for (unsigned i = 0; i < length; ++i) { | 355 for (unsigned i = 0; i < length; ++i) { |
356 __ dd(stack_checks_[i].id); | 356 __ dd(stack_checks_[i].id.ToInt()); |
357 __ dd(stack_checks_[i].pc_and_state); | 357 __ dd(stack_checks_[i].pc_and_state); |
358 } | 358 } |
359 return offset; | 359 return offset; |
360 } | 360 } |
361 | 361 |
362 | 362 |
363 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { | 363 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { |
364 // Fill in the deoptimization information. | 364 // Fill in the deoptimization information. |
365 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); | 365 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); |
366 if (!info_->HasDeoptimizationSupport()) return; | 366 if (!info_->HasDeoptimizationSupport()) return; |
367 int length = bailout_entries_.length(); | 367 int length = bailout_entries_.length(); |
368 Handle<DeoptimizationOutputData> data = isolate()->factory()-> | 368 Handle<DeoptimizationOutputData> data = isolate()->factory()-> |
369 NewDeoptimizationOutputData(length, TENURED); | 369 NewDeoptimizationOutputData(length, TENURED); |
370 for (int i = 0; i < length; i++) { | 370 for (int i = 0; i < length; i++) { |
371 data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id)); | 371 data->SetAstId(i, bailout_entries_[i].id); |
372 data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); | 372 data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); |
373 } | 373 } |
374 code->set_deoptimization_data(*data); | 374 code->set_deoptimization_data(*data); |
375 } | 375 } |
376 | 376 |
377 | 377 |
378 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) { | 378 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) { |
379 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo(); | 379 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo(); |
380 info->set_ic_total_count(ic_total_count_); | 380 info->set_ic_total_count(ic_total_count_); |
381 ASSERT(!isolate()->heap()->InNewSpace(*info)); | 381 ASSERT(!isolate()->heap()->InNewSpace(*info)); |
(...skipping 15 matching lines...) Expand all Loading... |
397 } | 397 } |
398 | 398 |
399 | 399 |
400 void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) { | 400 void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) { |
401 if (type_feedback_cells_.is_empty()) return; | 401 if (type_feedback_cells_.is_empty()) return; |
402 int length = type_feedback_cells_.length(); | 402 int length = type_feedback_cells_.length(); |
403 int array_size = TypeFeedbackCells::LengthOfFixedArray(length); | 403 int array_size = TypeFeedbackCells::LengthOfFixedArray(length); |
404 Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast( | 404 Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast( |
405 isolate()->factory()->NewFixedArray(array_size, TENURED)); | 405 isolate()->factory()->NewFixedArray(array_size, TENURED)); |
406 for (int i = 0; i < length; i++) { | 406 for (int i = 0; i < length; i++) { |
407 cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id)); | 407 cache->SetAstId(i, type_feedback_cells_[i].ast_id); |
408 cache->SetCell(i, *type_feedback_cells_[i].cell); | 408 cache->SetCell(i, *type_feedback_cells_[i].cell); |
409 } | 409 } |
410 TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells( | 410 TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells( |
411 *cache); | 411 *cache); |
412 } | 412 } |
413 | 413 |
414 | 414 |
415 | 415 |
416 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) { | 416 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) { |
417 PrepareForBailoutForId(node->id(), state); | 417 PrepareForBailoutForId(node->id(), state); |
(...skipping 10 matching lines...) Expand all Loading... |
428 PrepareForBailoutForId(call->ReturnId(), TOS_REG); | 428 PrepareForBailoutForId(call->ReturnId(), TOS_REG); |
429 #ifdef DEBUG | 429 #ifdef DEBUG |
430 // In debug builds, mark the return so we can verify that this function | 430 // In debug builds, mark the return so we can verify that this function |
431 // was called. | 431 // was called. |
432 ASSERT(!call->return_is_recorded_); | 432 ASSERT(!call->return_is_recorded_); |
433 call->return_is_recorded_ = true; | 433 call->return_is_recorded_ = true; |
434 #endif | 434 #endif |
435 } | 435 } |
436 | 436 |
437 | 437 |
438 void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) { | 438 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) { |
439 // There's no need to prepare this code for bailouts from already optimized | 439 // There's no need to prepare this code for bailouts from already optimized |
440 // code or code that can't be optimized. | 440 // code or code that can't be optimized. |
441 if (!info_->HasDeoptimizationSupport()) return; | 441 if (!info_->HasDeoptimizationSupport()) return; |
442 unsigned pc_and_state = | 442 unsigned pc_and_state = |
443 StateField::encode(state) | PcField::encode(masm_->pc_offset()); | 443 StateField::encode(state) | PcField::encode(masm_->pc_offset()); |
444 ASSERT(Smi::IsValid(pc_and_state)); | 444 ASSERT(Smi::IsValid(pc_and_state)); |
445 BailoutEntry entry = { id, pc_and_state }; | 445 BailoutEntry entry = { id, pc_and_state }; |
446 #ifdef DEBUG | 446 #ifdef DEBUG |
447 if (FLAG_enable_slow_asserts) { | 447 if (FLAG_enable_slow_asserts) { |
448 // Assert that we don't have multiple bailout entries for the same node. | 448 // Assert that we don't have multiple bailout entries for the same node. |
449 for (int i = 0; i < bailout_entries_.length(); i++) { | 449 for (int i = 0; i < bailout_entries_.length(); i++) { |
450 if (bailout_entries_.at(i).id == entry.id) { | 450 if (bailout_entries_.at(i).id == entry.id) { |
451 AstPrinter printer; | 451 AstPrinter printer; |
452 PrintF("%s", printer.PrintProgram(info_->function())); | 452 PrintF("%s", printer.PrintProgram(info_->function())); |
453 UNREACHABLE(); | 453 UNREACHABLE(); |
454 } | 454 } |
455 } | 455 } |
456 } | 456 } |
457 #endif // DEBUG | 457 #endif // DEBUG |
458 bailout_entries_.Add(entry, zone()); | 458 bailout_entries_.Add(entry, zone()); |
459 } | 459 } |
460 | 460 |
461 | 461 |
462 void FullCodeGenerator::RecordTypeFeedbackCell( | 462 void FullCodeGenerator::RecordTypeFeedbackCell( |
463 unsigned id, Handle<JSGlobalPropertyCell> cell) { | 463 TypeFeedbackId id, Handle<JSGlobalPropertyCell> cell) { |
464 TypeFeedbackCellEntry entry = { id, cell }; | 464 TypeFeedbackCellEntry entry = { id, cell }; |
465 type_feedback_cells_.Add(entry, zone()); | 465 type_feedback_cells_.Add(entry, zone()); |
466 } | 466 } |
467 | 467 |
468 | 468 |
469 void FullCodeGenerator::RecordStackCheck(unsigned ast_id) { | 469 void FullCodeGenerator::RecordStackCheck(BailoutId ast_id) { |
470 // The pc offset does not need to be encoded and packed together with a | 470 // The pc offset does not need to be encoded and packed together with a |
471 // state. | 471 // state. |
472 ASSERT(masm_->pc_offset() > 0); | 472 ASSERT(masm_->pc_offset() > 0); |
473 BailoutEntry entry = { ast_id, static_cast<unsigned>(masm_->pc_offset()) }; | 473 BailoutEntry entry = { ast_id, static_cast<unsigned>(masm_->pc_offset()) }; |
474 stack_checks_.Add(entry, zone()); | 474 stack_checks_.Add(entry, zone()); |
475 } | 475 } |
476 | 476 |
477 | 477 |
478 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { | 478 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { |
479 // Inline smi case inside loops, but not division and modulo which | 479 // Inline smi case inside loops, but not division and modulo which |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 VisitForEffect(expr->left()); | 802 VisitForEffect(expr->left()); |
803 VisitInDuplicateContext(expr->right()); | 803 VisitInDuplicateContext(expr->right()); |
804 } | 804 } |
805 | 805 |
806 | 806 |
807 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { | 807 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { |
808 bool is_logical_and = expr->op() == Token::AND; | 808 bool is_logical_and = expr->op() == Token::AND; |
809 Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR"); | 809 Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR"); |
810 Expression* left = expr->left(); | 810 Expression* left = expr->left(); |
811 Expression* right = expr->right(); | 811 Expression* right = expr->right(); |
812 int right_id = expr->RightId(); | 812 BailoutId right_id = expr->RightId(); |
813 Label done; | 813 Label done; |
814 | 814 |
815 if (context()->IsTest()) { | 815 if (context()->IsTest()) { |
816 Label eval_right; | 816 Label eval_right; |
817 const TestContext* test = TestContext::cast(context()); | 817 const TestContext* test = TestContext::cast(context()); |
818 if (is_logical_and) { | 818 if (is_logical_and) { |
819 VisitForControl(left, &eval_right, test->false_label(), &eval_right); | 819 VisitForControl(left, &eval_right, test->false_label(), &eval_right); |
820 } else { | 820 } else { |
821 VisitForControl(left, test->true_label(), &eval_right, &eval_right); | 821 VisitForControl(left, test->true_label(), &eval_right, &eval_right); |
822 } | 822 } |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 } | 1421 } |
1422 | 1422 |
1423 return false; | 1423 return false; |
1424 } | 1424 } |
1425 | 1425 |
1426 | 1426 |
1427 #undef __ | 1427 #undef __ |
1428 | 1428 |
1429 | 1429 |
1430 } } // namespace v8::internal | 1430 } } // namespace v8::internal |
OLD | NEW |