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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 72 |
73 #ifdef ENABLE_DEBUGGER_SUPPORT | 73 #ifdef ENABLE_DEBUGGER_SUPPORT |
74 void DeoptimizerData::Iterate(ObjectVisitor* v) { | 74 void DeoptimizerData::Iterate(ObjectVisitor* v) { |
75 if (deoptimized_frame_info_ != NULL) { | 75 if (deoptimized_frame_info_ != NULL) { |
76 deoptimized_frame_info_->Iterate(v); | 76 deoptimized_frame_info_->Iterate(v); |
77 } | 77 } |
78 } | 78 } |
79 #endif | 79 #endif |
80 | 80 |
81 | 81 |
| 82 Code* DeoptimizerData::FindDeoptimizingCode(Address addr) { |
| 83 for (DeoptimizingCodeListNode* node = deoptimizing_code_list_; |
| 84 node != NULL; |
| 85 node = node->next()) { |
| 86 if (node->code()->contains(addr)) return *node->code(); |
| 87 } |
| 88 return NULL; |
| 89 } |
| 90 |
| 91 |
| 92 void DeoptimizerData::RemoveDeoptimizingCode(Code* code) { |
| 93 for (DeoptimizingCodeListNode *prev = NULL, *cur = deoptimizing_code_list_; |
| 94 cur != NULL; |
| 95 prev = cur, cur = cur->next()) { |
| 96 if (*cur->code() == code) { |
| 97 if (prev == NULL) { |
| 98 deoptimizing_code_list_ = cur->next(); |
| 99 } else { |
| 100 prev->set_next(cur->next()); |
| 101 } |
| 102 delete cur; |
| 103 return; |
| 104 } |
| 105 } |
| 106 // Deoptimizing code is removed through weak callback. Each object is expected |
| 107 // to be removed once and only once. |
| 108 UNREACHABLE(); |
| 109 } |
| 110 |
| 111 |
82 // We rely on this function not causing a GC. It is called from generated code | 112 // We rely on this function not causing a GC. It is called from generated code |
83 // without having a real stack frame in place. | 113 // without having a real stack frame in place. |
84 Deoptimizer* Deoptimizer::New(JSFunction* function, | 114 Deoptimizer* Deoptimizer::New(JSFunction* function, |
85 BailoutType type, | 115 BailoutType type, |
86 unsigned bailout_id, | 116 unsigned bailout_id, |
87 Address from, | 117 Address from, |
88 int fp_to_sp_delta, | 118 int fp_to_sp_delta, |
89 Isolate* isolate) { | 119 Isolate* isolate) { |
90 ASSERT(isolate == Isolate::Current()); | 120 ASSERT(isolate == Isolate::Current()); |
91 Deoptimizer* deoptimizer = new Deoptimizer(isolate, | 121 Deoptimizer* deoptimizer = new Deoptimizer(isolate, |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 449 |
420 // Run through the list of all native contexts and deoptimize. | 450 // Run through the list of all native contexts and deoptimize. |
421 Object* context = Isolate::Current()->heap()->native_contexts_list(); | 451 Object* context = Isolate::Current()->heap()->native_contexts_list(); |
422 while (!context->IsUndefined()) { | 452 while (!context->IsUndefined()) { |
423 DeoptimizeAllFunctionsForContext(Context::cast(context), filter); | 453 DeoptimizeAllFunctionsForContext(Context::cast(context), filter); |
424 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 454 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |
425 } | 455 } |
426 } | 456 } |
427 | 457 |
428 | 458 |
429 void Deoptimizer::HandleWeakDeoptimizedCode( | 459 void Deoptimizer::HandleWeakDeoptimizedCode(v8::Persistent<v8::Value> obj, |
430 v8::Persistent<v8::Value> obj, void* data) { | 460 void* parameter) { |
431 DeoptimizingCodeListNode* node = | 461 DeoptimizingCodeListNode* node = |
432 reinterpret_cast<DeoptimizingCodeListNode*>(data); | 462 reinterpret_cast<DeoptimizingCodeListNode*>(parameter); |
433 RemoveDeoptimizingCode(*node->code()); | 463 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
| 464 data->RemoveDeoptimizingCode(*node->code()); |
434 #ifdef DEBUG | 465 #ifdef DEBUG |
435 node = Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; | 466 for (DeoptimizingCodeListNode* current = data->deoptimizing_code_list_; |
436 while (node != NULL) { | 467 current != NULL; |
437 ASSERT(node != reinterpret_cast<DeoptimizingCodeListNode*>(data)); | 468 current = current->next()) { |
438 node = node->next(); | 469 ASSERT(current != node); |
439 } | 470 } |
440 #endif | 471 #endif |
441 } | 472 } |
442 | 473 |
443 | 474 |
444 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { | 475 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { |
445 deoptimizer->DoComputeOutputFrames(); | 476 deoptimizer->DoComputeOutputFrames(); |
446 } | 477 } |
447 | 478 |
448 | 479 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 unsigned id = Deoptimizer::GetDeoptimizationId( | 543 unsigned id = Deoptimizer::GetDeoptimizationId( |
513 info->target_address(), Deoptimizer::EAGER); | 544 info->target_address(), Deoptimizer::EAGER); |
514 if (id == bailout_id && last_comment != NULL) { | 545 if (id == bailout_id && last_comment != NULL) { |
515 PrintF(" %s\n", last_comment); | 546 PrintF(" %s\n", last_comment); |
516 break; | 547 break; |
517 } | 548 } |
518 } | 549 } |
519 } | 550 } |
520 } | 551 } |
521 } else if (type == LAZY) { | 552 } else if (type == LAZY) { |
522 compiled_code_ = FindDeoptimizingCodeFromAddress(from); | 553 compiled_code_ = isolate->deoptimizer_data()->FindDeoptimizingCode(from); |
523 if (compiled_code_ == NULL) { | 554 if (compiled_code_ == NULL) { |
524 compiled_code_ = | 555 compiled_code_ = |
525 static_cast<Code*>(isolate->heap()->FindCodeObject(from)); | 556 static_cast<Code*>(isolate->heap()->FindCodeObject(from)); |
526 } | 557 } |
527 ASSERT(compiled_code_ != NULL); | 558 ASSERT(compiled_code_ != NULL); |
528 } else if (type == OSR) { | 559 } else if (type == OSR) { |
529 // The function has already been optimized and we're transitioning | 560 // The function has already been optimized and we're transitioning |
530 // from the unoptimized shared version to the optimized one in the | 561 // from the unoptimized shared version to the optimized one in the |
531 // function. The return address (from) points to unoptimized code. | 562 // function. The return address (from) points to unoptimized code. |
532 compiled_code_ = function_->code(); | 563 compiled_code_ = function_->code(); |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 CPU::FlushICache(memory->address(), desc.instr_size); | 1558 CPU::FlushICache(memory->address(), desc.instr_size); |
1528 | 1559 |
1529 if (type == EAGER) { | 1560 if (type == EAGER) { |
1530 data->eager_deoptimization_entry_code_entries_ = entry_count; | 1561 data->eager_deoptimization_entry_code_entries_ = entry_count; |
1531 } else { | 1562 } else { |
1532 data->lazy_deoptimization_entry_code_entries_ = entry_count; | 1563 data->lazy_deoptimization_entry_code_entries_ = entry_count; |
1533 } | 1564 } |
1534 } | 1565 } |
1535 | 1566 |
1536 | 1567 |
1537 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { | |
1538 DeoptimizingCodeListNode* node = | |
1539 Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; | |
1540 while (node != NULL) { | |
1541 if (node->code()->contains(addr)) return *node->code(); | |
1542 node = node->next(); | |
1543 } | |
1544 return NULL; | |
1545 } | |
1546 | |
1547 | |
1548 void Deoptimizer::RemoveDeoptimizingCode(Code* code) { | |
1549 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); | |
1550 ASSERT(data->deoptimizing_code_list_ != NULL); | |
1551 // Run through the code objects to find this one and remove it. | |
1552 DeoptimizingCodeListNode* prev = NULL; | |
1553 DeoptimizingCodeListNode* current = data->deoptimizing_code_list_; | |
1554 while (current != NULL) { | |
1555 if (*current->code() == code) { | |
1556 // Unlink from list. If prev is NULL we are looking at the first element. | |
1557 if (prev == NULL) { | |
1558 data->deoptimizing_code_list_ = current->next(); | |
1559 } else { | |
1560 prev->set_next(current->next()); | |
1561 } | |
1562 delete current; | |
1563 return; | |
1564 } | |
1565 // Move to next in list. | |
1566 prev = current; | |
1567 current = current->next(); | |
1568 } | |
1569 // Deoptimizing code is removed through weak callback. Each object is expected | |
1570 // to be removed once and only once. | |
1571 UNREACHABLE(); | |
1572 } | |
1573 | |
1574 | |
1575 void Deoptimizer::ReplaceCodeForRelatedFunctions(JSFunction* function, | 1568 void Deoptimizer::ReplaceCodeForRelatedFunctions(JSFunction* function, |
1576 Code* code) { | 1569 Code* code) { |
1577 SharedFunctionInfo* shared = function->shared(); | 1570 SharedFunctionInfo* shared = function->shared(); |
1578 Object* undefined = Isolate::Current()->heap()->undefined_value(); | 1571 Object* undefined = Isolate::Current()->heap()->undefined_value(); |
1579 Object* current = function; | 1572 Object* current = function; |
1580 | 1573 |
1581 while (current != undefined) { | 1574 while (current != undefined) { |
1582 JSFunction* func = JSFunction::cast(current); | 1575 JSFunction* func = JSFunction::cast(current); |
1583 current = func->next_function_link(); | 1576 current = func->next_function_link(); |
1584 func->set_code(shared->code()); | 1577 func->set_code(shared->code()); |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 | 2090 |
2098 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2091 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
2099 v->VisitPointer(BitCast<Object**>(&function_)); | 2092 v->VisitPointer(BitCast<Object**>(&function_)); |
2100 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2093 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
2101 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2094 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
2102 } | 2095 } |
2103 | 2096 |
2104 #endif // ENABLE_DEBUGGER_SUPPORT | 2097 #endif // ENABLE_DEBUGGER_SUPPORT |
2105 | 2098 |
2106 } } // namespace v8::internal | 2099 } } // namespace v8::internal |
OLD | NEW |