| 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 MemoryChunk* Deoptimizer::eager_deoptimization_entry_code_ = NULL; | 42 DeoptimizerData::DeoptimizerData() { |
| 43 MemoryChunk* Deoptimizer::lazy_deoptimization_entry_code_ = NULL; | 43 eager_deoptimization_entry_code_ = NULL; |
| 44 Deoptimizer* Deoptimizer::current_ = NULL; | 44 lazy_deoptimization_entry_code_ = NULL; |
| 45 DeoptimizingCodeListNode* Deoptimizer::deoptimizing_code_list_ = NULL; | 45 current_ = NULL; |
| 46 deoptimizing_code_list_ = NULL; |
| 47 } |
| 46 | 48 |
| 47 | 49 |
| 50 DeoptimizerData::~DeoptimizerData() { |
| 51 if (eager_deoptimization_entry_code_ != NULL) { |
| 52 Isolate::Current()->memory_allocator()->Free( |
| 53 eager_deoptimization_entry_code_); |
| 54 eager_deoptimization_entry_code_ = NULL; |
| 55 } |
| 56 if (lazy_deoptimization_entry_code_ != NULL) { |
| 57 Isolate::Current()->memory_allocator()->Free( |
| 58 lazy_deoptimization_entry_code_); |
| 59 lazy_deoptimization_entry_code_ = NULL; |
| 60 } |
| 61 } |
| 62 |
| 48 Deoptimizer* Deoptimizer::New(JSFunction* function, | 63 Deoptimizer* Deoptimizer::New(JSFunction* function, |
| 49 BailoutType type, | 64 BailoutType type, |
| 50 unsigned bailout_id, | 65 unsigned bailout_id, |
| 51 Address from, | 66 Address from, |
| 52 int fp_to_sp_delta) { | 67 int fp_to_sp_delta, |
| 53 Deoptimizer* deoptimizer = | 68 Isolate* isolate) { |
| 54 new Deoptimizer(function, type, bailout_id, from, fp_to_sp_delta); | 69 ASSERT(isolate == Isolate::Current()); |
| 55 ASSERT(current_ == NULL); | 70 Deoptimizer* deoptimizer = new Deoptimizer(isolate, |
| 56 current_ = deoptimizer; | 71 function, |
| 72 type, |
| 73 bailout_id, |
| 74 from, |
| 75 fp_to_sp_delta); |
| 76 ASSERT(isolate->deoptimizer_data()->current_ == NULL); |
| 77 isolate->deoptimizer_data()->current_ = deoptimizer; |
| 57 return deoptimizer; | 78 return deoptimizer; |
| 58 } | 79 } |
| 59 | 80 |
| 60 | 81 |
| 61 Deoptimizer* Deoptimizer::Grab() { | 82 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { |
| 62 Deoptimizer* result = current_; | 83 ASSERT(isolate == Isolate::Current()); |
| 84 Deoptimizer* result = isolate->deoptimizer_data()->current_; |
| 63 ASSERT(result != NULL); | 85 ASSERT(result != NULL); |
| 64 result->DeleteFrameDescriptions(); | 86 result->DeleteFrameDescriptions(); |
| 65 current_ = NULL; | 87 isolate->deoptimizer_data()->current_ = NULL; |
| 66 return result; | 88 return result; |
| 67 } | 89 } |
| 68 | 90 |
| 69 | 91 |
| 70 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, | 92 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, |
| 71 int count, | 93 int count, |
| 72 BailoutType type) { | 94 BailoutType type) { |
| 73 TableEntryGenerator generator(masm, type, count); | 95 TableEntryGenerator generator(masm, type, count); |
| 74 generator.Generate(); | 96 generator.Generate(); |
| 75 } | 97 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 GlobalObject::cast(object)->global_context(), visitor); | 170 GlobalObject::cast(object)->global_context(), visitor); |
| 149 } | 171 } |
| 150 } | 172 } |
| 151 | 173 |
| 152 | 174 |
| 153 void Deoptimizer::VisitAllOptimizedFunctions( | 175 void Deoptimizer::VisitAllOptimizedFunctions( |
| 154 OptimizedFunctionVisitor* visitor) { | 176 OptimizedFunctionVisitor* visitor) { |
| 155 AssertNoAllocation no_allocation; | 177 AssertNoAllocation no_allocation; |
| 156 | 178 |
| 157 // Run through the list of all global contexts and deoptimize. | 179 // Run through the list of all global contexts and deoptimize. |
| 158 Object* global = Heap::global_contexts_list(); | 180 Object* global = Isolate::Current()->heap()->global_contexts_list(); |
| 159 while (!global->IsUndefined()) { | 181 while (!global->IsUndefined()) { |
| 160 VisitAllOptimizedFunctionsForGlobalObject(Context::cast(global)->global(), | 182 VisitAllOptimizedFunctionsForGlobalObject(Context::cast(global)->global(), |
| 161 visitor); | 183 visitor); |
| 162 global = Context::cast(global)->get(Context::NEXT_CONTEXT_LINK); | 184 global = Context::cast(global)->get(Context::NEXT_CONTEXT_LINK); |
| 163 } | 185 } |
| 164 } | 186 } |
| 165 | 187 |
| 166 | 188 |
| 167 void Deoptimizer::HandleWeakDeoptimizedCode( | 189 void Deoptimizer::HandleWeakDeoptimizedCode( |
| 168 v8::Persistent<v8::Value> obj, void* data) { | 190 v8::Persistent<v8::Value> obj, void* data) { |
| 169 DeoptimizingCodeListNode* node = | 191 DeoptimizingCodeListNode* node = |
| 170 reinterpret_cast<DeoptimizingCodeListNode*>(data); | 192 reinterpret_cast<DeoptimizingCodeListNode*>(data); |
| 171 RemoveDeoptimizingCode(*node->code()); | 193 RemoveDeoptimizingCode(*node->code()); |
| 172 #ifdef DEBUG | 194 #ifdef DEBUG |
| 173 node = Deoptimizer::deoptimizing_code_list_; | 195 node = Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; |
| 174 while (node != NULL) { | 196 while (node != NULL) { |
| 175 ASSERT(node != reinterpret_cast<DeoptimizingCodeListNode*>(data)); | 197 ASSERT(node != reinterpret_cast<DeoptimizingCodeListNode*>(data)); |
| 176 node = node->next(); | 198 node = node->next(); |
| 177 } | 199 } |
| 178 #endif | 200 #endif |
| 179 } | 201 } |
| 180 | 202 |
| 181 | 203 |
| 182 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { | 204 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer, |
| 205 Isolate* isolate) { |
| 183 deoptimizer->DoComputeOutputFrames(); | 206 deoptimizer->DoComputeOutputFrames(); |
| 184 } | 207 } |
| 185 | 208 |
| 186 | 209 |
| 187 Deoptimizer::Deoptimizer(JSFunction* function, | 210 Deoptimizer::Deoptimizer(Isolate* isolate, |
| 211 JSFunction* function, |
| 188 BailoutType type, | 212 BailoutType type, |
| 189 unsigned bailout_id, | 213 unsigned bailout_id, |
| 190 Address from, | 214 Address from, |
| 191 int fp_to_sp_delta) | 215 int fp_to_sp_delta) |
| 192 : function_(function), | 216 : isolate_(isolate), |
| 217 function_(function), |
| 193 bailout_id_(bailout_id), | 218 bailout_id_(bailout_id), |
| 194 bailout_type_(type), | 219 bailout_type_(type), |
| 195 from_(from), | 220 from_(from), |
| 196 fp_to_sp_delta_(fp_to_sp_delta), | 221 fp_to_sp_delta_(fp_to_sp_delta), |
| 197 output_count_(0), | 222 output_count_(0), |
| 198 output_(NULL), | 223 output_(NULL), |
| 199 integer32_values_(NULL), | 224 integer32_values_(NULL), |
| 200 double_values_(NULL) { | 225 double_values_(NULL) { |
| 201 if (FLAG_trace_deopt && type != OSR) { | 226 if (FLAG_trace_deopt && type != OSR) { |
| 202 PrintF("**** DEOPT: "); | 227 PrintF("**** DEOPT: "); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 221 optimized_code_ = FindDeoptimizingCodeFromAddress(from); | 246 optimized_code_ = FindDeoptimizingCodeFromAddress(from); |
| 222 ASSERT(optimized_code_ != NULL); | 247 ASSERT(optimized_code_ != NULL); |
| 223 } else if (type == OSR) { | 248 } else if (type == OSR) { |
| 224 // The function has already been optimized and we're transitioning | 249 // The function has already been optimized and we're transitioning |
| 225 // from the unoptimized shared version to the optimized one in the | 250 // from the unoptimized shared version to the optimized one in the |
| 226 // function. The return address (from) points to unoptimized code. | 251 // function. The return address (from) points to unoptimized code. |
| 227 optimized_code_ = function_->code(); | 252 optimized_code_ = function_->code(); |
| 228 ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION); | 253 ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION); |
| 229 ASSERT(!optimized_code_->contains(from)); | 254 ASSERT(!optimized_code_->contains(from)); |
| 230 } | 255 } |
| 231 ASSERT(Heap::allow_allocation(false)); | 256 ASSERT(HEAP->allow_allocation(false)); |
| 232 unsigned size = ComputeInputFrameSize(); | 257 unsigned size = ComputeInputFrameSize(); |
| 233 input_ = new(size) FrameDescription(size, function); | 258 input_ = new(size) FrameDescription(size, function); |
| 234 } | 259 } |
| 235 | 260 |
| 236 | 261 |
| 237 Deoptimizer::~Deoptimizer() { | 262 Deoptimizer::~Deoptimizer() { |
| 238 ASSERT(input_ == NULL && output_ == NULL); | 263 ASSERT(input_ == NULL && output_ == NULL); |
| 239 delete[] integer32_values_; | 264 delete[] integer32_values_; |
| 240 delete[] double_values_; | 265 delete[] double_values_; |
| 241 } | 266 } |
| 242 | 267 |
| 243 | 268 |
| 244 void Deoptimizer::DeleteFrameDescriptions() { | 269 void Deoptimizer::DeleteFrameDescriptions() { |
| 245 delete input_; | 270 delete input_; |
| 246 for (int i = 0; i < output_count_; ++i) { | 271 for (int i = 0; i < output_count_; ++i) { |
| 247 if (output_[i] != input_) delete output_[i]; | 272 if (output_[i] != input_) delete output_[i]; |
| 248 } | 273 } |
| 249 delete[] output_; | 274 delete[] output_; |
| 250 input_ = NULL; | 275 input_ = NULL; |
| 251 output_ = NULL; | 276 output_ = NULL; |
| 252 ASSERT(!Heap::allow_allocation(true)); | 277 ASSERT(!HEAP->allow_allocation(true)); |
| 253 } | 278 } |
| 254 | 279 |
| 255 | 280 |
| 256 Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { | 281 Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { |
| 257 ASSERT(id >= 0); | 282 ASSERT(id >= 0); |
| 258 if (id >= kNumberOfEntries) return NULL; | 283 if (id >= kNumberOfEntries) return NULL; |
| 259 MemoryChunk* base = NULL; | 284 MemoryChunk* base = NULL; |
| 285 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
| 260 if (type == EAGER) { | 286 if (type == EAGER) { |
| 261 if (eager_deoptimization_entry_code_ == NULL) { | 287 if (data->eager_deoptimization_entry_code_ == NULL) { |
| 262 eager_deoptimization_entry_code_ = CreateCode(type); | 288 data->eager_deoptimization_entry_code_ = CreateCode(type); |
| 263 } | 289 } |
| 264 base = eager_deoptimization_entry_code_; | 290 base = data->eager_deoptimization_entry_code_; |
| 265 } else { | 291 } else { |
| 266 if (lazy_deoptimization_entry_code_ == NULL) { | 292 if (data->lazy_deoptimization_entry_code_ == NULL) { |
| 267 lazy_deoptimization_entry_code_ = CreateCode(type); | 293 data->lazy_deoptimization_entry_code_ = CreateCode(type); |
| 268 } | 294 } |
| 269 base = lazy_deoptimization_entry_code_; | 295 base = data->lazy_deoptimization_entry_code_; |
| 270 } | 296 } |
| 271 return | 297 return |
| 272 static_cast<Address>(base->body()) + (id * table_entry_size_); | 298 static_cast<Address>(base->body()) + (id * table_entry_size_); |
| 273 } | 299 } |
| 274 | 300 |
| 275 | 301 |
| 276 int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { | 302 int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { |
| 277 MemoryChunk* base = NULL; | 303 MemoryChunk* base = NULL; |
| 304 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
| 278 if (type == EAGER) { | 305 if (type == EAGER) { |
| 279 base = eager_deoptimization_entry_code_; | 306 base = data->eager_deoptimization_entry_code_; |
| 280 } else { | 307 } else { |
| 281 base = lazy_deoptimization_entry_code_; | 308 base = data->lazy_deoptimization_entry_code_; |
| 282 } | 309 } |
| 283 if (base == NULL || | 310 if (base == NULL || |
| 284 addr < base->body() || | 311 addr < base->body() || |
| 285 addr >= base->body() + | 312 addr >= base->body() + |
| 286 (kNumberOfEntries * table_entry_size_)) { | 313 (kNumberOfEntries * table_entry_size_)) { |
| 287 return kNotDeoptimizationEntry; | 314 return kNotDeoptimizationEntry; |
| 288 } | 315 } |
| 289 ASSERT_EQ(0, | 316 ASSERT_EQ(0, |
| 290 static_cast<int>(addr - base->body()) % table_entry_size_); | 317 static_cast<int>(addr - base->body()) % table_entry_size_); |
| 291 return static_cast<int>(addr - base->body()) / table_entry_size_; | 318 return static_cast<int>(addr - base->body()) / table_entry_size_; |
| 292 } | 319 } |
| 293 | 320 |
| 294 | 321 |
| 295 void Deoptimizer::Setup() { | |
| 296 // Do nothing yet. | |
| 297 } | |
| 298 | |
| 299 | |
| 300 void Deoptimizer::TearDown() { | |
| 301 if (eager_deoptimization_entry_code_ != NULL) { | |
| 302 MemoryAllocator::Free(eager_deoptimization_entry_code_); | |
| 303 eager_deoptimization_entry_code_ = NULL; | |
| 304 } | |
| 305 if (lazy_deoptimization_entry_code_ != NULL) { | |
| 306 MemoryAllocator::Free(lazy_deoptimization_entry_code_); | |
| 307 lazy_deoptimization_entry_code_ = NULL; | |
| 308 } | |
| 309 } | |
| 310 | |
| 311 | |
| 312 int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data, | 322 int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data, |
| 313 unsigned id, | 323 unsigned id, |
| 314 SharedFunctionInfo* shared) { | 324 SharedFunctionInfo* shared) { |
| 315 // TODO(kasperl): For now, we do a simple linear search for the PC | 325 // 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 | 326 // offset associated with the given node id. This should probably be |
| 317 // changed to a binary search. | 327 // changed to a binary search. |
| 318 int length = data->DeoptPoints(); | 328 int length = data->DeoptPoints(); |
| 319 Smi* smi_id = Smi::FromInt(id); | 329 Smi* smi_id = Smi::FromInt(id); |
| 320 for (int i = 0; i < length; i++) { | 330 for (int i = 0; i < length; i++) { |
| 321 if (data->AstId(i) == smi_id) { | 331 if (data->AstId(i) == smi_id) { |
| 322 return data->PcAndState(i)->value(); | 332 return data->PcAndState(i)->value(); |
| 323 } | 333 } |
| 324 } | 334 } |
| 325 PrintF("[couldn't find pc offset for node=%u]\n", id); | 335 PrintF("[couldn't find pc offset for node=%u]\n", id); |
| 326 PrintF("[method: %s]\n", *shared->DebugName()->ToCString()); | 336 PrintF("[method: %s]\n", *shared->DebugName()->ToCString()); |
| 327 // Print the source code if available. | 337 // Print the source code if available. |
| 328 HeapStringAllocator string_allocator; | 338 HeapStringAllocator string_allocator; |
| 329 StringStream stream(&string_allocator); | 339 StringStream stream(&string_allocator); |
| 330 shared->SourceCodePrint(&stream, -1); | 340 shared->SourceCodePrint(&stream, -1); |
| 331 PrintF("[source:\n%s\n]", *stream.ToCString()); | 341 PrintF("[source:\n%s\n]", *stream.ToCString()); |
| 332 | 342 |
| 333 UNREACHABLE(); | 343 UNREACHABLE(); |
| 334 return -1; | 344 return -1; |
| 335 } | 345 } |
| 336 | 346 |
| 337 | 347 |
| 338 int Deoptimizer::GetDeoptimizedCodeCount() { | 348 int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) { |
| 339 int length = 0; | 349 int length = 0; |
| 340 DeoptimizingCodeListNode* node = Deoptimizer::deoptimizing_code_list_; | 350 DeoptimizingCodeListNode* node = |
| 351 isolate->deoptimizer_data()->deoptimizing_code_list_; |
| 341 while (node != NULL) { | 352 while (node != NULL) { |
| 342 length++; | 353 length++; |
| 343 node = node->next(); | 354 node = node->next(); |
| 344 } | 355 } |
| 345 return length; | 356 return length; |
| 346 } | 357 } |
| 347 | 358 |
| 348 | 359 |
| 349 void Deoptimizer::DoComputeOutputFrames() { | 360 void Deoptimizer::DoComputeOutputFrames() { |
| 350 if (bailout_type_ == OSR) { | 361 if (bailout_type_ == OSR) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 | 449 |
| 439 void Deoptimizer::InsertHeapNumberValue(JavaScriptFrame* frame, | 450 void Deoptimizer::InsertHeapNumberValue(JavaScriptFrame* frame, |
| 440 int stack_index, | 451 int stack_index, |
| 441 double val, | 452 double val, |
| 442 int extra_slot_count) { | 453 int extra_slot_count) { |
| 443 // Add one to the TOS index to take the 'state' pushed before jumping | 454 // Add one to the TOS index to take the 'state' pushed before jumping |
| 444 // to the stub that calls Runtime::NotifyDeoptimized into account. | 455 // to the stub that calls Runtime::NotifyDeoptimized into account. |
| 445 int tos_index = stack_index + extra_slot_count; | 456 int tos_index = stack_index + extra_slot_count; |
| 446 int index = (frame->ComputeExpressionsCount() - 1) - tos_index; | 457 int index = (frame->ComputeExpressionsCount() - 1) - tos_index; |
| 447 if (FLAG_trace_deopt) PrintF("Allocating a new heap number: %e\n", val); | 458 if (FLAG_trace_deopt) PrintF("Allocating a new heap number: %e\n", val); |
| 448 Handle<Object> num = Factory::NewNumber(val); | 459 Handle<Object> num = isolate_->factory()->NewNumber(val); |
| 449 frame->SetExpression(index, *num); | 460 frame->SetExpression(index, *num); |
| 450 } | 461 } |
| 451 | 462 |
| 452 | 463 |
| 453 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 464 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
| 454 int frame_index, | 465 int frame_index, |
| 455 unsigned output_offset) { | 466 unsigned output_offset) { |
| 456 disasm::NameConverter converter; | 467 disasm::NameConverter converter; |
| 457 // A GC-safe temporary placeholder that we can put in the output frame. | 468 // A GC-safe temporary placeholder that we can put in the output frame. |
| 458 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); | 469 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 } | 629 } |
| 619 | 630 |
| 620 case Translation::ARGUMENTS_OBJECT: { | 631 case Translation::ARGUMENTS_OBJECT: { |
| 621 // Use the arguments marker value as a sentinel and fill in the arguments | 632 // Use the arguments marker value as a sentinel and fill in the arguments |
| 622 // object after the deoptimized frame is built. | 633 // object after the deoptimized frame is built. |
| 623 ASSERT(frame_index == 0); // Only supported for first frame. | 634 ASSERT(frame_index == 0); // Only supported for first frame. |
| 624 if (FLAG_trace_deopt) { | 635 if (FLAG_trace_deopt) { |
| 625 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 636 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 626 output_[frame_index]->GetTop() + output_offset, | 637 output_[frame_index]->GetTop() + output_offset, |
| 627 output_offset); | 638 output_offset); |
| 628 Heap::arguments_marker()->ShortPrint(); | 639 isolate_->heap()->arguments_marker()->ShortPrint(); |
| 629 PrintF(" ; arguments object\n"); | 640 PrintF(" ; arguments object\n"); |
| 630 } | 641 } |
| 631 intptr_t value = reinterpret_cast<intptr_t>(Heap::arguments_marker()); | 642 intptr_t value = reinterpret_cast<intptr_t>( |
| 643 isolate_->heap()->arguments_marker()); |
| 632 output_[frame_index]->SetFrameSlot(output_offset, value); | 644 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 633 return; | 645 return; |
| 634 } | 646 } |
| 635 } | 647 } |
| 636 } | 648 } |
| 637 | 649 |
| 638 | 650 |
| 639 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, | 651 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator, |
| 640 int* input_offset) { | 652 int* input_offset) { |
| 641 disasm::NameConverter converter; | 653 disasm::NameConverter converter; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 ASSERT(!Serializer::enabled()); | 940 ASSERT(!Serializer::enabled()); |
| 929 | 941 |
| 930 MacroAssembler masm(NULL, 16 * KB); | 942 MacroAssembler masm(NULL, 16 * KB); |
| 931 masm.set_emit_debug_code(false); | 943 masm.set_emit_debug_code(false); |
| 932 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); | 944 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); |
| 933 CodeDesc desc; | 945 CodeDesc desc; |
| 934 masm.GetCode(&desc); | 946 masm.GetCode(&desc); |
| 935 ASSERT(desc.reloc_size == 0); | 947 ASSERT(desc.reloc_size == 0); |
| 936 | 948 |
| 937 MemoryChunk* chunk = | 949 MemoryChunk* chunk = |
| 938 MemoryAllocator::AllocateChunk(desc.instr_size, EXECUTABLE, NULL); | 950 Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size, |
| 951 EXECUTABLE, |
| 952 NULL); |
| 939 memcpy(chunk->body(), desc.buffer, desc.instr_size); | 953 memcpy(chunk->body(), desc.buffer, desc.instr_size); |
| 940 CPU::FlushICache(chunk->body(), desc.instr_size); | 954 CPU::FlushICache(chunk->body(), desc.instr_size); |
| 941 return chunk; | 955 return chunk; |
| 942 } | 956 } |
| 943 | 957 |
| 944 | 958 |
| 945 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { | 959 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { |
| 946 DeoptimizingCodeListNode* node = Deoptimizer::deoptimizing_code_list_; | 960 DeoptimizingCodeListNode* node = |
| 961 Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; |
| 947 while (node != NULL) { | 962 while (node != NULL) { |
| 948 if (node->code()->contains(addr)) return *node->code(); | 963 if (node->code()->contains(addr)) return *node->code(); |
| 949 node = node->next(); | 964 node = node->next(); |
| 950 } | 965 } |
| 951 return NULL; | 966 return NULL; |
| 952 } | 967 } |
| 953 | 968 |
| 954 | 969 |
| 955 void Deoptimizer::RemoveDeoptimizingCode(Code* code) { | 970 void Deoptimizer::RemoveDeoptimizingCode(Code* code) { |
| 956 ASSERT(deoptimizing_code_list_ != NULL); | 971 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
| 972 ASSERT(data->deoptimizing_code_list_ != NULL); |
| 957 // Run through the code objects to find this one and remove it. | 973 // Run through the code objects to find this one and remove it. |
| 958 DeoptimizingCodeListNode* prev = NULL; | 974 DeoptimizingCodeListNode* prev = NULL; |
| 959 DeoptimizingCodeListNode* current = deoptimizing_code_list_; | 975 DeoptimizingCodeListNode* current = data->deoptimizing_code_list_; |
| 960 while (current != NULL) { | 976 while (current != NULL) { |
| 961 if (*current->code() == code) { | 977 if (*current->code() == code) { |
| 962 // Unlink from list. If prev is NULL we are looking at the first element. | 978 // Unlink from list. If prev is NULL we are looking at the first element. |
| 963 if (prev == NULL) { | 979 if (prev == NULL) { |
| 964 deoptimizing_code_list_ = current->next(); | 980 data->deoptimizing_code_list_ = current->next(); |
| 965 } else { | 981 } else { |
| 966 prev->set_next(current->next()); | 982 prev->set_next(current->next()); |
| 967 } | 983 } |
| 968 delete current; | 984 delete current; |
| 969 return; | 985 return; |
| 970 } | 986 } |
| 971 // Move to next in list. | 987 // Move to next in list. |
| 972 prev = current; | 988 prev = current; |
| 973 current = current->next(); | 989 current = current->next(); |
| 974 } | 990 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 } | 1057 } |
| 1042 // The bits encode the sign in the least significant bit. | 1058 // The bits encode the sign in the least significant bit. |
| 1043 bool is_negative = (bits & 1) == 1; | 1059 bool is_negative = (bits & 1) == 1; |
| 1044 int32_t result = bits >> 1; | 1060 int32_t result = bits >> 1; |
| 1045 return is_negative ? -result : result; | 1061 return is_negative ? -result : result; |
| 1046 } | 1062 } |
| 1047 | 1063 |
| 1048 | 1064 |
| 1049 Handle<ByteArray> TranslationBuffer::CreateByteArray() { | 1065 Handle<ByteArray> TranslationBuffer::CreateByteArray() { |
| 1050 int length = contents_.length(); | 1066 int length = contents_.length(); |
| 1051 Handle<ByteArray> result = Factory::NewByteArray(length, TENURED); | 1067 Handle<ByteArray> result = |
| 1068 Isolate::Current()->factory()->NewByteArray(length, TENURED); |
| 1052 memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length); | 1069 memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length); |
| 1053 return result; | 1070 return result; |
| 1054 } | 1071 } |
| 1055 | 1072 |
| 1056 | 1073 |
| 1057 void Translation::BeginFrame(int node_id, int literal_id, unsigned height) { | 1074 void Translation::BeginFrame(int node_id, int literal_id, unsigned height) { |
| 1058 buffer_->Add(FRAME); | 1075 buffer_->Add(FRAME); |
| 1059 buffer_->Add(node_id); | 1076 buffer_->Add(node_id); |
| 1060 buffer_->Add(literal_id); | 1077 buffer_->Add(literal_id); |
| 1061 buffer_->Add(height); | 1078 buffer_->Add(height); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 return "DUPLICATE"; | 1181 return "DUPLICATE"; |
| 1165 } | 1182 } |
| 1166 UNREACHABLE(); | 1183 UNREACHABLE(); |
| 1167 return ""; | 1184 return ""; |
| 1168 } | 1185 } |
| 1169 | 1186 |
| 1170 #endif | 1187 #endif |
| 1171 | 1188 |
| 1172 | 1189 |
| 1173 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { | 1190 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { |
| 1191 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
| 1174 // Globalize the code object and make it weak. | 1192 // Globalize the code object and make it weak. |
| 1175 code_ = Handle<Code>::cast((GlobalHandles::Create(code))); | 1193 code_ = Handle<Code>::cast(global_handles->Create(code)); |
| 1176 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(code_.location()), | 1194 global_handles->MakeWeak(reinterpret_cast<Object**>(code_.location()), |
| 1177 this, | 1195 this, |
| 1178 Deoptimizer::HandleWeakDeoptimizedCode); | 1196 Deoptimizer::HandleWeakDeoptimizedCode); |
| 1179 } | 1197 } |
| 1180 | 1198 |
| 1181 | 1199 |
| 1182 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { | 1200 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { |
| 1183 GlobalHandles::Destroy(reinterpret_cast<Object**>(code_.location())); | 1201 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
| 1202 global_handles->Destroy(reinterpret_cast<Object**>(code_.location())); |
| 1184 } | 1203 } |
| 1185 | 1204 |
| 1186 | 1205 |
| 1187 } } // namespace v8::internal | 1206 } } // namespace v8::internal |
| OLD | NEW |