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

Side by Side Diff: src/deoptimizer.cc

Issue 11275145: Decouple allocation and creation of deopt tables (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years, 1 month 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/deoptimizer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 23 matching lines...) Expand all
34 #include "full-codegen.h" 34 #include "full-codegen.h"
35 #include "global-handles.h" 35 #include "global-handles.h"
36 #include "macro-assembler.h" 36 #include "macro-assembler.h"
37 #include "prettyprinter.h" 37 #include "prettyprinter.h"
38 38
39 39
40 namespace v8 { 40 namespace v8 {
41 namespace internal { 41 namespace internal {
42 42
43 DeoptimizerData::DeoptimizerData() { 43 DeoptimizerData::DeoptimizerData() {
44 eager_deoptimization_entry_code_ = NULL; 44 eager_deoptimization_entry_code_entries_ = -1;
45 lazy_deoptimization_entry_code_ = NULL; 45 lazy_deoptimization_entry_code_entries_ = -1;
46 size_t deopt_table_size = Deoptimizer::GetMaxDeoptTableSize();
47 eager_deoptimization_entry_code_ = new VirtualMemory(deopt_table_size);
48 lazy_deoptimization_entry_code_ = new VirtualMemory(deopt_table_size);
46 current_ = NULL; 49 current_ = NULL;
47 deoptimizing_code_list_ = NULL; 50 deoptimizing_code_list_ = NULL;
48 #ifdef ENABLE_DEBUGGER_SUPPORT 51 #ifdef ENABLE_DEBUGGER_SUPPORT
49 deoptimized_frame_info_ = NULL; 52 deoptimized_frame_info_ = NULL;
50 #endif 53 #endif
51 } 54 }
52 55
53 56
54 DeoptimizerData::~DeoptimizerData() { 57 DeoptimizerData::~DeoptimizerData() {
55 if (eager_deoptimization_entry_code_ != NULL) { 58 delete eager_deoptimization_entry_code_;
56 Isolate::Current()->memory_allocator()->Free( 59 eager_deoptimization_entry_code_ = NULL;
57 eager_deoptimization_entry_code_); 60 delete lazy_deoptimization_entry_code_;
58 eager_deoptimization_entry_code_ = NULL; 61 lazy_deoptimization_entry_code_ = NULL;
59 } 62
60 if (lazy_deoptimization_entry_code_ != NULL) {
61 Isolate::Current()->memory_allocator()->Free(
62 lazy_deoptimization_entry_code_);
63 lazy_deoptimization_entry_code_ = NULL;
64 }
65 DeoptimizingCodeListNode* current = deoptimizing_code_list_; 63 DeoptimizingCodeListNode* current = deoptimizing_code_list_;
66 while (current != NULL) { 64 while (current != NULL) {
67 DeoptimizingCodeListNode* prev = current; 65 DeoptimizingCodeListNode* prev = current;
68 current = current->next(); 66 current = current->next();
69 delete prev; 67 delete prev;
70 } 68 }
71 deoptimizing_code_list_ = NULL; 69 deoptimizing_code_list_ = NULL;
72 } 70 }
73 71
74 72
(...skipping 21 matching lines...) Expand all
96 bailout_id, 94 bailout_id,
97 from, 95 from,
98 fp_to_sp_delta, 96 fp_to_sp_delta,
99 NULL); 97 NULL);
100 ASSERT(isolate->deoptimizer_data()->current_ == NULL); 98 ASSERT(isolate->deoptimizer_data()->current_ == NULL);
101 isolate->deoptimizer_data()->current_ = deoptimizer; 99 isolate->deoptimizer_data()->current_ = deoptimizer;
102 return deoptimizer; 100 return deoptimizer;
103 } 101 }
104 102
105 103
104 // No larger than 2K on all platforms
105 static const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
106
107
108 size_t Deoptimizer::GetMaxDeoptTableSize() {
109 size_t entries_size =
110 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
111 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
112 OS::CommitPageSize()) + 1;
113 return OS::CommitPageSize() * page_count;
114 }
115
116
106 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { 117 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
107 ASSERT(isolate == Isolate::Current()); 118 ASSERT(isolate == Isolate::Current());
108 Deoptimizer* result = isolate->deoptimizer_data()->current_; 119 Deoptimizer* result = isolate->deoptimizer_data()->current_;
109 ASSERT(result != NULL); 120 ASSERT(result != NULL);
110 result->DeleteFrameDescriptions(); 121 result->DeleteFrameDescriptions();
111 isolate->deoptimizer_data()->current_ = NULL; 122 isolate->deoptimizer_data()->current_ = NULL;
112 return result; 123 return result;
113 } 124 }
114 125
115 126
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 for (int i = 0; i < output_count_; ++i) { 465 for (int i = 0; i < output_count_; ++i) {
455 if (output_[i] != input_) delete output_[i]; 466 if (output_[i] != input_) delete output_[i];
456 } 467 }
457 delete[] output_; 468 delete[] output_;
458 input_ = NULL; 469 input_ = NULL;
459 output_ = NULL; 470 output_ = NULL;
460 ASSERT(!HEAP->allow_allocation(true)); 471 ASSERT(!HEAP->allow_allocation(true));
461 } 472 }
462 473
463 474
464 Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { 475 Address Deoptimizer::GetDeoptimizationEntry(int id,
476 BailoutType type,
477 GetEntryMode mode) {
465 ASSERT(id >= 0); 478 ASSERT(id >= 0);
466 if (id >= kNumberOfEntries) return NULL; 479 if (id >= kMaxNumberOfEntries) return NULL;
467 MemoryChunk* base = NULL; 480 VirtualMemory* base = NULL;
468 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); 481 if (mode == ENSURE_ENTRY_CODE) {
469 if (type == EAGER) { 482 EnsureCodeForDeoptimizationEntry(type, id);
470 if (data->eager_deoptimization_entry_code_ == NULL) {
471 data->eager_deoptimization_entry_code_ = CreateCode(type);
472 }
473 base = data->eager_deoptimization_entry_code_;
474 } else { 483 } else {
475 if (data->lazy_deoptimization_entry_code_ == NULL) { 484 ASSERT(mode == CALCULATE_ENTRY_ADDRESS);
476 data->lazy_deoptimization_entry_code_ = CreateCode(type);
477 }
478 base = data->lazy_deoptimization_entry_code_;
479 } 485 }
480 return
481 static_cast<Address>(base->area_start()) + (id * table_entry_size_);
482 }
483
484
485 int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) {
486 MemoryChunk* base = NULL;
487 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); 486 DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
488 if (type == EAGER) { 487 if (type == EAGER) {
489 base = data->eager_deoptimization_entry_code_; 488 base = data->eager_deoptimization_entry_code_;
490 } else { 489 } else {
491 base = data->lazy_deoptimization_entry_code_; 490 base = data->lazy_deoptimization_entry_code_;
492 } 491 }
492 return
493 static_cast<Address>(base->address()) + (id * table_entry_size_);
494 }
495
496
497 int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) {
498 VirtualMemory* base = NULL;
499 DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
500 if (type == EAGER) {
501 base = data->eager_deoptimization_entry_code_;
502 } else {
503 base = data->lazy_deoptimization_entry_code_;
504 }
505 Address base_casted = reinterpret_cast<Address>(base->address());
493 if (base == NULL || 506 if (base == NULL ||
494 addr < base->area_start() || 507 addr < base->address() ||
495 addr >= base->area_start() + 508 addr >= base_casted + (kMaxNumberOfEntries * table_entry_size_)) {
496 (kNumberOfEntries * table_entry_size_)) {
497 return kNotDeoptimizationEntry; 509 return kNotDeoptimizationEntry;
498 } 510 }
499 ASSERT_EQ(0, 511 ASSERT_EQ(0,
500 static_cast<int>(addr - base->area_start()) % table_entry_size_); 512 static_cast<int>(addr - base_casted) % table_entry_size_);
501 return static_cast<int>(addr - base->area_start()) / table_entry_size_; 513 return static_cast<int>(addr - base_casted) / table_entry_size_;
502 } 514 }
503 515
504 516
505 int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data, 517 int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
506 BailoutId id, 518 BailoutId id,
507 SharedFunctionInfo* shared) { 519 SharedFunctionInfo* shared) {
508 // TODO(kasperl): For now, we do a simple linear search for the PC 520 // TODO(kasperl): For now, we do a simple linear search for the PC
509 // offset associated with the given node id. This should probably be 521 // offset associated with the given node id. This should probably be
510 // changed to a binary search. 522 // changed to a binary search.
511 int length = data->DeoptPoints(); 523 int length = data->DeoptPoints();
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 } 1389 }
1378 1390
1379 1391
1380 void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) { 1392 void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) {
1381 HeapNumberMaterializationDescriptor value_desc( 1393 HeapNumberMaterializationDescriptor value_desc(
1382 reinterpret_cast<Address>(slot_address), value); 1394 reinterpret_cast<Address>(slot_address), value);
1383 deferred_heap_numbers_.Add(value_desc); 1395 deferred_heap_numbers_.Add(value_desc);
1384 } 1396 }
1385 1397
1386 1398
1387 MemoryChunk* Deoptimizer::CreateCode(BailoutType type) { 1399 void Deoptimizer::EnsureCodeForDeoptimizationEntry(BailoutType type,
1400 int max_entry_id) {
1388 // We cannot run this if the serializer is enabled because this will 1401 // We cannot run this if the serializer is enabled because this will
1389 // cause us to emit relocation information for the external 1402 // cause us to emit relocation information for the external
1390 // references. This is fine because the deoptimizer's code section 1403 // references. This is fine because the deoptimizer's code section
1391 // isn't meant to be serialized at all. 1404 // isn't meant to be serialized at all.
1392 ASSERT(!Serializer::enabled()); 1405 ASSERT(!Serializer::enabled());
1393 1406
1407 ASSERT(type == EAGER || type == LAZY);
1408 DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
1409 int entry_count = (type == EAGER)
1410 ? data->eager_deoptimization_entry_code_entries_
1411 : data->lazy_deoptimization_entry_code_entries_;
1412 if (max_entry_id < entry_count) return;
1413 entry_count = Min(Max(entry_count * 2, Deoptimizer::kMinNumberOfEntries),
1414 Deoptimizer::kMaxNumberOfEntries);
1415
1394 MacroAssembler masm(Isolate::Current(), NULL, 16 * KB); 1416 MacroAssembler masm(Isolate::Current(), NULL, 16 * KB);
1395 masm.set_emit_debug_code(false); 1417 masm.set_emit_debug_code(false);
1396 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); 1418 GenerateDeoptimizationEntries(&masm, entry_count, type);
1397 CodeDesc desc; 1419 CodeDesc desc;
1398 masm.GetCode(&desc); 1420 masm.GetCode(&desc);
1399 ASSERT(desc.reloc_size == 0); 1421 ASSERT(desc.reloc_size == 0);
1400 1422
1401 MemoryChunk* chunk = 1423 VirtualMemory* memory = type == EAGER
1402 Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size, 1424 ? data->eager_deoptimization_entry_code_
1403 EXECUTABLE, 1425 : data->lazy_deoptimization_entry_code_;
1404 NULL); 1426 size_t table_size = Deoptimizer::GetMaxDeoptTableSize();
1405 ASSERT(chunk->area_size() >= desc.instr_size); 1427 ASSERT(static_cast<int>(table_size) >= desc.instr_size);
1406 if (chunk == NULL) { 1428 memory->Commit(memory->address(), table_size, true);
1407 V8::FatalProcessOutOfMemory("Not enough memory for deoptimization table"); 1429 memcpy(memory->address(), desc.buffer, desc.instr_size);
1430 CPU::FlushICache(memory->address(), desc.instr_size);
1431
1432 if (type == EAGER) {
1433 data->eager_deoptimization_entry_code_entries_ = entry_count;
1434 } else {
1435 data->lazy_deoptimization_entry_code_entries_ = entry_count;
1408 } 1436 }
1409 memcpy(chunk->area_start(), desc.buffer, desc.instr_size);
1410 CPU::FlushICache(chunk->area_start(), desc.instr_size);
1411 return chunk;
1412 } 1437 }
1413 1438
1414 1439
1415 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { 1440 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) {
1416 DeoptimizingCodeListNode* node = 1441 DeoptimizingCodeListNode* node =
1417 Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; 1442 Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_;
1418 while (node != NULL) { 1443 while (node != NULL) {
1419 if (node->code()->contains(addr)) return *node->code(); 1444 if (node->code()->contains(addr)) return *node->code();
1420 node = node->next(); 1445 node = node->next();
1421 } 1446 }
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 2021
1997 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 2022 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
1998 v->VisitPointer(BitCast<Object**>(&function_)); 2023 v->VisitPointer(BitCast<Object**>(&function_));
1999 v->VisitPointers(parameters_, parameters_ + parameters_count_); 2024 v->VisitPointers(parameters_, parameters_ + parameters_count_);
2000 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 2025 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
2001 } 2026 }
2002 2027
2003 #endif // ENABLE_DEBUGGER_SUPPORT 2028 #endif // ENABLE_DEBUGGER_SUPPORT
2004 2029
2005 } } // namespace v8::internal 2030 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698