| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 21 matching lines...) Expand all Loading... |
| 32 #include "disasm.h" | 32 #include "disasm.h" |
| 33 #include "full-codegen.h" | 33 #include "full-codegen.h" |
| 34 #include "global-handles.h" | 34 #include "global-handles.h" |
| 35 #include "macro-assembler.h" | 35 #include "macro-assembler.h" |
| 36 #include "prettyprinter.h" | 36 #include "prettyprinter.h" |
| 37 | 37 |
| 38 | 38 |
| 39 namespace v8 { | 39 namespace v8 { |
| 40 namespace internal { | 40 namespace internal { |
| 41 | 41 |
| 42 LargeObjectChunk* Deoptimizer::eager_deoptimization_entry_code_ = NULL; | 42 MemoryChunk* Deoptimizer::eager_deoptimization_entry_code_ = NULL; |
| 43 LargeObjectChunk* Deoptimizer::lazy_deoptimization_entry_code_ = NULL; | 43 MemoryChunk* Deoptimizer::lazy_deoptimization_entry_code_ = NULL; |
| 44 Deoptimizer* Deoptimizer::current_ = NULL; | 44 Deoptimizer* Deoptimizer::current_ = NULL; |
| 45 DeoptimizingCodeListNode* Deoptimizer::deoptimizing_code_list_ = NULL; | 45 DeoptimizingCodeListNode* Deoptimizer::deoptimizing_code_list_ = NULL; |
| 46 | 46 |
| 47 | 47 |
| 48 Deoptimizer* Deoptimizer::New(JSFunction* function, | 48 Deoptimizer* Deoptimizer::New(JSFunction* function, |
| 49 BailoutType type, | 49 BailoutType type, |
| 50 unsigned bailout_id, | 50 unsigned bailout_id, |
| 51 Address from, | 51 Address from, |
| 52 int fp_to_sp_delta) { | 52 int fp_to_sp_delta) { |
| 53 Deoptimizer* deoptimizer = | 53 Deoptimizer* deoptimizer = |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 delete[] output_; | 249 delete[] output_; |
| 250 input_ = NULL; | 250 input_ = NULL; |
| 251 output_ = NULL; | 251 output_ = NULL; |
| 252 ASSERT(!Heap::allow_allocation(true)); | 252 ASSERT(!Heap::allow_allocation(true)); |
| 253 } | 253 } |
| 254 | 254 |
| 255 | 255 |
| 256 Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { | 256 Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { |
| 257 ASSERT(id >= 0); | 257 ASSERT(id >= 0); |
| 258 if (id >= kNumberOfEntries) return NULL; | 258 if (id >= kNumberOfEntries) return NULL; |
| 259 LargeObjectChunk* base = NULL; | 259 MemoryChunk* base = NULL; |
| 260 if (type == EAGER) { | 260 if (type == EAGER) { |
| 261 if (eager_deoptimization_entry_code_ == NULL) { | 261 if (eager_deoptimization_entry_code_ == NULL) { |
| 262 eager_deoptimization_entry_code_ = CreateCode(type); | 262 eager_deoptimization_entry_code_ = CreateCode(type); |
| 263 } | 263 } |
| 264 base = eager_deoptimization_entry_code_; | 264 base = eager_deoptimization_entry_code_; |
| 265 } else { | 265 } else { |
| 266 if (lazy_deoptimization_entry_code_ == NULL) { | 266 if (lazy_deoptimization_entry_code_ == NULL) { |
| 267 lazy_deoptimization_entry_code_ = CreateCode(type); | 267 lazy_deoptimization_entry_code_ = CreateCode(type); |
| 268 } | 268 } |
| 269 base = lazy_deoptimization_entry_code_; | 269 base = lazy_deoptimization_entry_code_; |
| 270 } | 270 } |
| 271 return | 271 return |
| 272 static_cast<Address>(base->GetStartAddress()) + (id * table_entry_size_); | 272 static_cast<Address>(base->body()) + (id * table_entry_size_); |
| 273 } | 273 } |
| 274 | 274 |
| 275 | 275 |
| 276 int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { | 276 int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { |
| 277 LargeObjectChunk* base = NULL; | 277 MemoryChunk* base = NULL; |
| 278 if (type == EAGER) { | 278 if (type == EAGER) { |
| 279 base = eager_deoptimization_entry_code_; | 279 base = eager_deoptimization_entry_code_; |
| 280 } else { | 280 } else { |
| 281 base = lazy_deoptimization_entry_code_; | 281 base = lazy_deoptimization_entry_code_; |
| 282 } | 282 } |
| 283 if (base == NULL || | 283 if (base == NULL || |
| 284 addr < base->GetStartAddress() || | 284 addr < base->body() || |
| 285 addr >= base->GetStartAddress() + | 285 addr >= base->body() + |
| 286 (kNumberOfEntries * table_entry_size_)) { | 286 (kNumberOfEntries * table_entry_size_)) { |
| 287 return kNotDeoptimizationEntry; | 287 return kNotDeoptimizationEntry; |
| 288 } | 288 } |
| 289 ASSERT_EQ(0, | 289 ASSERT_EQ(0, |
| 290 static_cast<int>(addr - base->GetStartAddress()) % table_entry_size_); | 290 static_cast<int>(addr - base->body()) % table_entry_size_); |
| 291 return static_cast<int>(addr - base->GetStartAddress()) / table_entry_size_; | 291 return static_cast<int>(addr - base->body()) / table_entry_size_; |
| 292 } | 292 } |
| 293 | 293 |
| 294 | 294 |
| 295 void Deoptimizer::Setup() { | 295 void Deoptimizer::Setup() { |
| 296 // Do nothing yet. | 296 // Do nothing yet. |
| 297 } | 297 } |
| 298 | 298 |
| 299 | 299 |
| 300 void Deoptimizer::TearDown() { | 300 void Deoptimizer::TearDown() { |
| 301 if (eager_deoptimization_entry_code_ != NULL) { | 301 if (eager_deoptimization_entry_code_ != NULL) { |
| 302 eager_deoptimization_entry_code_->Free(EXECUTABLE); | 302 MemoryAllocator::Free(eager_deoptimization_entry_code_); |
| 303 eager_deoptimization_entry_code_ = NULL; | 303 eager_deoptimization_entry_code_ = NULL; |
| 304 } | 304 } |
| 305 if (lazy_deoptimization_entry_code_ != NULL) { | 305 if (lazy_deoptimization_entry_code_ != NULL) { |
| 306 lazy_deoptimization_entry_code_->Free(EXECUTABLE); | 306 MemoryAllocator::Free(lazy_deoptimization_entry_code_); |
| 307 lazy_deoptimization_entry_code_ = NULL; | 307 lazy_deoptimization_entry_code_ = NULL; |
| 308 } | 308 } |
| 309 } | 309 } |
| 310 | 310 |
| 311 | 311 |
| 312 unsigned Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data, | 312 unsigned Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data, |
| 313 unsigned id, | 313 unsigned id, |
| 314 SharedFunctionInfo* shared) { | 314 SharedFunctionInfo* shared) { |
| 315 // TODO(kasperl): For now, we do a simple linear search for the PC | 315 // TODO(kasperl): For now, we do a simple linear search for the PC |
| 316 // offset associated with the given node id. This should probably be | 316 // offset associated with the given node id. This should probably be |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 | 872 |
| 873 | 873 |
| 874 void Deoptimizer::AddDoubleValue(int frame_index, | 874 void Deoptimizer::AddDoubleValue(int frame_index, |
| 875 int slot_index, | 875 int slot_index, |
| 876 double value) { | 876 double value) { |
| 877 ValueDescriptionDouble value_desc(slot_index, value); | 877 ValueDescriptionDouble value_desc(slot_index, value); |
| 878 double_values_[frame_index].Add(value_desc); | 878 double_values_[frame_index].Add(value_desc); |
| 879 } | 879 } |
| 880 | 880 |
| 881 | 881 |
| 882 LargeObjectChunk* Deoptimizer::CreateCode(BailoutType type) { | 882 MemoryChunk* Deoptimizer::CreateCode(BailoutType type) { |
| 883 // We cannot run this if the serializer is enabled because this will | 883 // We cannot run this if the serializer is enabled because this will |
| 884 // cause us to emit relocation information for the external | 884 // cause us to emit relocation information for the external |
| 885 // references. This is fine because the deoptimizer's code section | 885 // references. This is fine because the deoptimizer's code section |
| 886 // isn't meant to be serialized at all. | 886 // isn't meant to be serialized at all. |
| 887 ASSERT(!Serializer::enabled()); | 887 ASSERT(!Serializer::enabled()); |
| 888 bool old_debug_code = FLAG_debug_code; | 888 bool old_debug_code = FLAG_debug_code; |
| 889 FLAG_debug_code = false; | 889 FLAG_debug_code = false; |
| 890 | 890 |
| 891 MacroAssembler masm(NULL, 16 * KB); | 891 MacroAssembler masm(NULL, 16 * KB); |
| 892 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); | 892 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); |
| 893 CodeDesc desc; | 893 CodeDesc desc; |
| 894 masm.GetCode(&desc); | 894 masm.GetCode(&desc); |
| 895 ASSERT(desc.reloc_size == 0); | 895 ASSERT(desc.reloc_size == 0); |
| 896 | 896 |
| 897 LargeObjectChunk* chunk = LargeObjectChunk::New(desc.instr_size, EXECUTABLE); | 897 MemoryChunk* chunk = |
| 898 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); | 898 MemoryAllocator::AllocateChunk(desc.instr_size, EXECUTABLE, NULL); |
| 899 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); | 899 memcpy(chunk->body(), desc.buffer, desc.instr_size); |
| 900 CPU::FlushICache(chunk->body(), desc.instr_size); |
| 900 FLAG_debug_code = old_debug_code; | 901 FLAG_debug_code = old_debug_code; |
| 901 return chunk; | 902 return chunk; |
| 902 } | 903 } |
| 903 | 904 |
| 904 | 905 |
| 905 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { | 906 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { |
| 906 DeoptimizingCodeListNode* node = Deoptimizer::deoptimizing_code_list_; | 907 DeoptimizingCodeListNode* node = Deoptimizer::deoptimizing_code_list_; |
| 907 while (node != NULL) { | 908 while (node != NULL) { |
| 908 if (node->code()->contains(addr)) return *node->code(); | 909 if (node->code()->contains(addr)) return *node->code(); |
| 909 node = node->next(); | 910 node = node->next(); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 Deoptimizer::HandleWeakDeoptimizedCode); | 1139 Deoptimizer::HandleWeakDeoptimizedCode); |
| 1139 } | 1140 } |
| 1140 | 1141 |
| 1141 | 1142 |
| 1142 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { | 1143 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { |
| 1143 GlobalHandles::Destroy(reinterpret_cast<Object**>(code_.location())); | 1144 GlobalHandles::Destroy(reinterpret_cast<Object**>(code_.location())); |
| 1144 } | 1145 } |
| 1145 | 1146 |
| 1146 | 1147 |
| 1147 } } // namespace v8::internal | 1148 } } // namespace v8::internal |
| OLD | NEW |