OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 BailoutType type) { | 278 BailoutType type) { |
279 TableEntryGenerator generator(masm, type, count); | 279 TableEntryGenerator generator(masm, type, count); |
280 generator.Generate(); | 280 generator.Generate(); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 void Deoptimizer::VisitAllOptimizedFunctionsForContext( | 284 void Deoptimizer::VisitAllOptimizedFunctionsForContext( |
285 Context* context, OptimizedFunctionVisitor* visitor) { | 285 Context* context, OptimizedFunctionVisitor* visitor) { |
286 Isolate* isolate = context->GetIsolate(); | 286 Isolate* isolate = context->GetIsolate(); |
287 ZoneScope zone_scope(isolate->runtime_zone(), DELETE_ON_EXIT); | 287 ZoneScope zone_scope(isolate->runtime_zone(), DELETE_ON_EXIT); |
288 AssertNoAllocation no_allocation; | 288 DisallowHeapAllocation no_allocation; |
289 | 289 |
290 ASSERT(context->IsNativeContext()); | 290 ASSERT(context->IsNativeContext()); |
291 | 291 |
292 visitor->EnterContext(context); | 292 visitor->EnterContext(context); |
293 | 293 |
294 // Create a snapshot of the optimized functions list. This is needed because | 294 // Create a snapshot of the optimized functions list. This is needed because |
295 // visitors might remove more than one link from the list at once. | 295 // visitors might remove more than one link from the list at once. |
296 ZoneList<JSFunction*> snapshot(1, isolate->runtime_zone()); | 296 ZoneList<JSFunction*> snapshot(1, isolate->runtime_zone()); |
297 Object* element = context->OptimizedFunctionsListHead(); | 297 Object* element = context->OptimizedFunctionsListHead(); |
298 while (!element->IsUndefined()) { | 298 while (!element->IsUndefined()) { |
299 JSFunction* element_function = JSFunction::cast(element); | 299 JSFunction* element_function = JSFunction::cast(element); |
300 snapshot.Add(element_function, isolate->runtime_zone()); | 300 snapshot.Add(element_function, isolate->runtime_zone()); |
301 element = element_function->next_function_link(); | 301 element = element_function->next_function_link(); |
302 } | 302 } |
303 | 303 |
304 // Run through the snapshot of optimized functions and visit them. | 304 // Run through the snapshot of optimized functions and visit them. |
305 for (int i = 0; i < snapshot.length(); ++i) { | 305 for (int i = 0; i < snapshot.length(); ++i) { |
306 visitor->VisitFunction(snapshot.at(i)); | 306 visitor->VisitFunction(snapshot.at(i)); |
307 } | 307 } |
308 | 308 |
309 visitor->LeaveContext(context); | 309 visitor->LeaveContext(context); |
310 } | 310 } |
311 | 311 |
312 | 312 |
313 void Deoptimizer::VisitAllOptimizedFunctions( | 313 void Deoptimizer::VisitAllOptimizedFunctions( |
314 Isolate* isolate, | 314 Isolate* isolate, |
315 OptimizedFunctionVisitor* visitor) { | 315 OptimizedFunctionVisitor* visitor) { |
316 AssertNoAllocation no_allocation; | 316 DisallowHeapAllocation no_allocation; |
317 | 317 |
318 // Run through the list of all native contexts and deoptimize. | 318 // Run through the list of all native contexts and deoptimize. |
319 Object* context = isolate->heap()->native_contexts_list(); | 319 Object* context = isolate->heap()->native_contexts_list(); |
320 while (!context->IsUndefined()) { | 320 while (!context->IsUndefined()) { |
321 VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor); | 321 VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor); |
322 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 322 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |
323 } | 323 } |
324 } | 324 } |
325 | 325 |
326 | 326 |
327 // Removes the functions selected by the given filter from the optimized | 327 // Removes the functions selected by the given filter from the optimized |
328 // function list of the given context and partitions the removed functions | 328 // function list of the given context and partitions the removed functions |
329 // into one or more lists such that all functions in a list share the same | 329 // into one or more lists such that all functions in a list share the same |
330 // code. The head of each list is written in the deoptimizing_functions field | 330 // code. The head of each list is written in the deoptimizing_functions field |
331 // of the corresponding code object. | 331 // of the corresponding code object. |
332 // The found code objects are returned in the given zone list. | 332 // The found code objects are returned in the given zone list. |
333 static void PartitionOptimizedFunctions(Context* context, | 333 static void PartitionOptimizedFunctions(Context* context, |
334 OptimizedFunctionFilter* filter, | 334 OptimizedFunctionFilter* filter, |
335 ZoneList<Code*>* partitions, | 335 ZoneList<Code*>* partitions, |
336 Zone* zone, | 336 Zone* zone, |
337 Object* undefined) { | 337 Object* undefined) { |
338 AssertNoAllocation no_allocation; | 338 DisallowHeapAllocation no_allocation; |
339 Object* current = context->get(Context::OPTIMIZED_FUNCTIONS_LIST); | 339 Object* current = context->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
340 Object* remainder_head = undefined; | 340 Object* remainder_head = undefined; |
341 Object* remainder_tail = undefined; | 341 Object* remainder_tail = undefined; |
342 ASSERT_EQ(0, partitions->length()); | 342 ASSERT_EQ(0, partitions->length()); |
343 while (current != undefined) { | 343 while (current != undefined) { |
344 JSFunction* function = JSFunction::cast(current); | 344 JSFunction* function = JSFunction::cast(current); |
345 current = function->next_function_link(); | 345 current = function->next_function_link(); |
346 if (filter->TakeFunction(function)) { | 346 if (filter->TakeFunction(function)) { |
347 Code* code = function->code(); | 347 Code* code = function->code(); |
348 if (code->deoptimizing_functions() == undefined) { | 348 if (code->deoptimizing_functions() == undefined) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 explicit DeoptimizeWithMatchingCodeFilter(Code* code) : code_(code) {} | 381 explicit DeoptimizeWithMatchingCodeFilter(Code* code) : code_(code) {} |
382 virtual bool TakeFunction(JSFunction* function) { | 382 virtual bool TakeFunction(JSFunction* function) { |
383 return function->code() == code_; | 383 return function->code() == code_; |
384 } | 384 } |
385 private: | 385 private: |
386 Code* code_; | 386 Code* code_; |
387 }; | 387 }; |
388 | 388 |
389 | 389 |
390 void Deoptimizer::DeoptimizeAll(Isolate* isolate) { | 390 void Deoptimizer::DeoptimizeAll(Isolate* isolate) { |
391 AssertNoAllocation no_allocation; | 391 DisallowHeapAllocation no_allocation; |
392 | 392 |
393 if (FLAG_trace_deopt) { | 393 if (FLAG_trace_deopt) { |
394 PrintF("[deoptimize all contexts]\n"); | 394 PrintF("[deoptimize all contexts]\n"); |
395 } | 395 } |
396 | 396 |
397 DeoptimizeAllFilter filter; | 397 DeoptimizeAllFilter filter; |
398 DeoptimizeAllFunctionsWith(isolate, &filter); | 398 DeoptimizeAllFunctionsWith(isolate, &filter); |
399 } | 399 } |
400 | 400 |
401 | 401 |
402 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { | 402 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { |
403 AssertNoAllocation no_allocation; | 403 DisallowHeapAllocation no_allocation; |
404 DeoptimizeAllFilter filter; | 404 DeoptimizeAllFilter filter; |
405 if (object->IsJSGlobalProxy()) { | 405 if (object->IsJSGlobalProxy()) { |
406 Object* proto = object->GetPrototype(); | 406 Object* proto = object->GetPrototype(); |
407 ASSERT(proto->IsJSGlobalObject()); | 407 ASSERT(proto->IsJSGlobalObject()); |
408 DeoptimizeAllFunctionsForContext( | 408 DeoptimizeAllFunctionsForContext( |
409 GlobalObject::cast(proto)->native_context(), &filter); | 409 GlobalObject::cast(proto)->native_context(), &filter); |
410 } else if (object->IsGlobalObject()) { | 410 } else if (object->IsGlobalObject()) { |
411 DeoptimizeAllFunctionsForContext( | 411 DeoptimizeAllFunctionsForContext( |
412 GlobalObject::cast(object)->native_context(), &filter); | 412 GlobalObject::cast(object)->native_context(), &filter); |
413 } | 413 } |
(...skipping 30 matching lines...) Expand all Loading... |
444 for (int i = 0; i < codes.length(); ++i) { | 444 for (int i = 0; i < codes.length(); ++i) { |
445 DeoptimizeFunctionWithPreparedFunctionList( | 445 DeoptimizeFunctionWithPreparedFunctionList( |
446 JSFunction::cast(codes.at(i)->deoptimizing_functions())); | 446 JSFunction::cast(codes.at(i)->deoptimizing_functions())); |
447 codes.at(i)->set_deoptimizing_functions(undefined); | 447 codes.at(i)->set_deoptimizing_functions(undefined); |
448 } | 448 } |
449 } | 449 } |
450 | 450 |
451 | 451 |
452 void Deoptimizer::DeoptimizeAllFunctionsWith(Isolate* isolate, | 452 void Deoptimizer::DeoptimizeAllFunctionsWith(Isolate* isolate, |
453 OptimizedFunctionFilter* filter) { | 453 OptimizedFunctionFilter* filter) { |
454 AssertNoAllocation no_allocation; | 454 DisallowHeapAllocation no_allocation; |
455 | 455 |
456 // Run through the list of all native contexts and deoptimize. | 456 // Run through the list of all native contexts and deoptimize. |
457 Object* context = isolate->heap()->native_contexts_list(); | 457 Object* context = isolate->heap()->native_contexts_list(); |
458 while (!context->IsUndefined()) { | 458 while (!context->IsUndefined()) { |
459 DeoptimizeAllFunctionsForContext(Context::cast(context), filter); | 459 DeoptimizeAllFunctionsForContext(Context::cast(context), filter); |
460 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 460 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |
461 } | 461 } |
462 } | 462 } |
463 | 463 |
464 | 464 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 int opt_count = function->shared()->opt_count(); | 551 int opt_count = function->shared()->opt_count(); |
552 if (opt_count > 0) opt_count--; | 552 if (opt_count > 0) opt_count--; |
553 function->shared()->set_opt_count(opt_count); | 553 function->shared()->set_opt_count(opt_count); |
554 } | 554 } |
555 } | 555 } |
556 compiled_code_ = FindOptimizedCode(function, optimized_code); | 556 compiled_code_ = FindOptimizedCode(function, optimized_code); |
557 StackFrame::Type frame_type = function == NULL | 557 StackFrame::Type frame_type = function == NULL |
558 ? StackFrame::STUB | 558 ? StackFrame::STUB |
559 : StackFrame::JAVA_SCRIPT; | 559 : StackFrame::JAVA_SCRIPT; |
560 trace_ = TraceEnabledFor(type, frame_type); | 560 trace_ = TraceEnabledFor(type, frame_type); |
561 ASSERT(HEAP->allow_allocation(false)); | 561 ASSERT(AllowHeapAllocation::IsAllowed()); |
| 562 AllowHeapAllocation::SetIsAllowed(false); |
562 unsigned size = ComputeInputFrameSize(); | 563 unsigned size = ComputeInputFrameSize(); |
563 input_ = new(size) FrameDescription(size, function); | 564 input_ = new(size) FrameDescription(size, function); |
564 input_->SetFrameType(frame_type); | 565 input_->SetFrameType(frame_type); |
565 } | 566 } |
566 | 567 |
567 | 568 |
568 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, | 569 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, |
569 Code* optimized_code) { | 570 Code* optimized_code) { |
570 switch (bailout_type_) { | 571 switch (bailout_type_) { |
571 case Deoptimizer::SOFT: | 572 case Deoptimizer::SOFT: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 | 613 |
613 | 614 |
614 void Deoptimizer::DeleteFrameDescriptions() { | 615 void Deoptimizer::DeleteFrameDescriptions() { |
615 delete input_; | 616 delete input_; |
616 for (int i = 0; i < output_count_; ++i) { | 617 for (int i = 0; i < output_count_; ++i) { |
617 if (output_[i] != input_) delete output_[i]; | 618 if (output_[i] != input_) delete output_[i]; |
618 } | 619 } |
619 delete[] output_; | 620 delete[] output_; |
620 input_ = NULL; | 621 input_ = NULL; |
621 output_ = NULL; | 622 output_ = NULL; |
622 ASSERT(!HEAP->allow_allocation(true)); | 623 ASSERT(!AllowHeapAllocation::IsAllowed()); |
| 624 AllowHeapAllocation::SetIsAllowed(true); |
623 } | 625 } |
624 | 626 |
625 | 627 |
626 Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate, | 628 Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate, |
627 int id, | 629 int id, |
628 BailoutType type, | 630 BailoutType type, |
629 GetEntryMode mode) { | 631 GetEntryMode mode) { |
630 ASSERT(id >= 0); | 632 ASSERT(id >= 0); |
631 if (id >= kMaxNumberOfEntries) return NULL; | 633 if (id >= kMaxNumberOfEntries) return NULL; |
632 if (mode == ENSURE_ENTRY_CODE) { | 634 if (mode == ENSURE_ENTRY_CODE) { |
(...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2848 for (int i = 0; i < args_slots->length(); ++i) { | 2850 for (int i = 0; i < args_slots->length(); ++i) { |
2849 (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame); | 2851 (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame); |
2850 } | 2852 } |
2851 } | 2853 } |
2852 | 2854 |
2853 | 2855 |
2854 Vector<SlotRef> SlotRef::ComputeSlotMappingForArguments( | 2856 Vector<SlotRef> SlotRef::ComputeSlotMappingForArguments( |
2855 JavaScriptFrame* frame, | 2857 JavaScriptFrame* frame, |
2856 int inlined_jsframe_index, | 2858 int inlined_jsframe_index, |
2857 int formal_parameter_count) { | 2859 int formal_parameter_count) { |
2858 AssertNoAllocation no_gc; | 2860 DisallowHeapAllocation no_gc; |
2859 int deopt_index = Safepoint::kNoDeoptimizationIndex; | 2861 int deopt_index = Safepoint::kNoDeoptimizationIndex; |
2860 DeoptimizationInputData* data = | 2862 DeoptimizationInputData* data = |
2861 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); | 2863 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
2862 TranslationIterator it(data->TranslationByteArray(), | 2864 TranslationIterator it(data->TranslationByteArray(), |
2863 data->TranslationIndex(deopt_index)->value()); | 2865 data->TranslationIndex(deopt_index)->value()); |
2864 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); | 2866 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
2865 ASSERT(opcode == Translation::BEGIN); | 2867 ASSERT(opcode == Translation::BEGIN); |
2866 it.Next(); // Drop frame count. | 2868 it.Next(); // Drop frame count. |
2867 int jsframe_count = it.Next(); | 2869 int jsframe_count = it.Next(); |
2868 USE(jsframe_count); | 2870 USE(jsframe_count); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2950 | 2952 |
2951 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2953 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
2952 v->VisitPointer(BitCast<Object**>(&function_)); | 2954 v->VisitPointer(BitCast<Object**>(&function_)); |
2953 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2955 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
2954 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2956 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
2955 } | 2957 } |
2956 | 2958 |
2957 #endif // ENABLE_DEBUGGER_SUPPORT | 2959 #endif // ENABLE_DEBUGGER_SUPPORT |
2958 | 2960 |
2959 } } // namespace v8::internal | 2961 } } // namespace v8::internal |
OLD | NEW |