| 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 |