| 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 8276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8287 ASSERT(args.length() == 1); | 8287 ASSERT(args.length() == 1); |
| 8288 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 8288 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 8289 ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation); | 8289 ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation); |
| 8290 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 8290 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
| 8291 return function->code(); | 8291 return function->code(); |
| 8292 } | 8292 } |
| 8293 | 8293 |
| 8294 | 8294 |
| 8295 class ActivationsFinder : public ThreadVisitor { | 8295 class ActivationsFinder : public ThreadVisitor { |
| 8296 public: | 8296 public: |
| 8297 explicit ActivationsFinder(JSFunction* function) | 8297 Code* code_; |
| 8298 : function_(function), has_activations_(false) {} | 8298 bool has_code_activations_; |
| 8299 |
| 8300 explicit ActivationsFinder(Code* code) |
| 8301 : code_(code), |
| 8302 has_code_activations_(false) { } |
| 8299 | 8303 |
| 8300 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 8304 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
| 8301 if (has_activations_) return; | 8305 JavaScriptFrameIterator it(isolate, top); |
| 8306 VisitFrames(&it); |
| 8307 } |
| 8302 | 8308 |
| 8303 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 8309 void VisitFrames(JavaScriptFrameIterator* it) { |
| 8304 JavaScriptFrame* frame = it.frame(); | 8310 for (; !it->done(); it->Advance()) { |
| 8305 if (frame->is_optimized() && frame->function() == function_) { | 8311 JavaScriptFrame* frame = it->frame(); |
| 8306 has_activations_ = true; | 8312 if (code_->contains(frame->pc())) has_code_activations_ = true; |
| 8307 return; | |
| 8308 } | |
| 8309 } | 8313 } |
| 8310 } | 8314 } |
| 8311 | |
| 8312 bool has_activations() { return has_activations_; } | |
| 8313 | |
| 8314 private: | |
| 8315 JSFunction* function_; | |
| 8316 bool has_activations_; | |
| 8317 }; | 8315 }; |
| 8318 | 8316 |
| 8319 | 8317 |
| 8320 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) { | 8318 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) { |
| 8321 HandleScope scope(isolate); | 8319 HandleScope scope(isolate); |
| 8322 ASSERT(args.length() == 0); | 8320 ASSERT(args.length() == 0); |
| 8323 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); | 8321 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
| 8324 ASSERT(AllowHeapAllocation::IsAllowed()); | 8322 ASSERT(AllowHeapAllocation::IsAllowed()); |
| 8325 delete deoptimizer; | 8323 delete deoptimizer; |
| 8326 return isolate->heap()->undefined_value(); | 8324 return isolate->heap()->undefined_value(); |
| 8327 } | 8325 } |
| 8328 | 8326 |
| 8329 | 8327 |
| 8330 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { | 8328 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { |
| 8331 HandleScope scope(isolate); | 8329 HandleScope scope(isolate); |
| 8332 ASSERT(args.length() == 1); | 8330 ASSERT(args.length() == 1); |
| 8333 RUNTIME_ASSERT(args[0]->IsSmi()); | 8331 RUNTIME_ASSERT(args[0]->IsSmi()); |
| 8334 Deoptimizer::BailoutType type = | 8332 Deoptimizer::BailoutType type = |
| 8335 static_cast<Deoptimizer::BailoutType>(args.smi_at(0)); | 8333 static_cast<Deoptimizer::BailoutType>(args.smi_at(0)); |
| 8336 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); | 8334 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
| 8337 ASSERT(AllowHeapAllocation::IsAllowed()); | 8335 ASSERT(AllowHeapAllocation::IsAllowed()); |
| 8338 | 8336 |
| 8339 ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION); | 8337 Handle<JSFunction> function = deoptimizer->function(); |
| 8338 Handle<Code> optimized_code = deoptimizer->compiled_code(); |
| 8339 |
| 8340 ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION); |
| 8341 ASSERT(type == deoptimizer->bailout_type()); |
| 8340 | 8342 |
| 8341 // Make sure to materialize objects before causing any allocation. | 8343 // Make sure to materialize objects before causing any allocation. |
| 8342 JavaScriptFrameIterator it(isolate); | 8344 JavaScriptFrameIterator it(isolate); |
| 8343 deoptimizer->MaterializeHeapObjects(&it); | 8345 deoptimizer->MaterializeHeapObjects(&it); |
| 8344 delete deoptimizer; | 8346 delete deoptimizer; |
| 8345 | 8347 |
| 8346 JavaScriptFrame* frame = it.frame(); | 8348 JavaScriptFrame* frame = it.frame(); |
| 8347 RUNTIME_ASSERT(frame->function()->IsJSFunction()); | 8349 RUNTIME_ASSERT(frame->function()->IsJSFunction()); |
| 8348 Handle<JSFunction> function(frame->function(), isolate); | |
| 8349 Handle<Code> optimized_code(function->code()); | |
| 8350 RUNTIME_ASSERT((type != Deoptimizer::EAGER && | |
| 8351 type != Deoptimizer::SOFT) || function->IsOptimized()); | |
| 8352 | 8350 |
| 8353 // Avoid doing too much work when running with --always-opt and keep | 8351 // Avoid doing too much work when running with --always-opt and keep |
| 8354 // the optimized code around. | 8352 // the optimized code around. |
| 8355 if (FLAG_always_opt || type == Deoptimizer::LAZY) { | 8353 if (FLAG_always_opt || type == Deoptimizer::LAZY) { |
| 8356 return isolate->heap()->undefined_value(); | 8354 return isolate->heap()->undefined_value(); |
| 8357 } | 8355 } |
| 8358 | 8356 |
| 8359 // Find other optimized activations of the function or functions that | 8357 // Search for other activations of the same function and code. |
| 8360 // share the same optimized code. | 8358 ActivationsFinder activations_finder(*optimized_code); |
| 8361 bool has_other_activations = false; | 8359 activations_finder.VisitFrames(&it); |
| 8362 while (!it.done()) { | 8360 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); |
| 8363 JavaScriptFrame* frame = it.frame(); | 8361 |
| 8364 JSFunction* other_function = frame->function(); | 8362 if (!activations_finder.has_code_activations_) { |
| 8365 if (frame->is_optimized() && other_function->code() == function->code()) { | 8363 if (function->code() == *optimized_code) { |
| 8366 has_other_activations = true; | 8364 if (FLAG_trace_deopt) { |
| 8367 break; | 8365 PrintF("[removing optimized code for: "); |
| 8366 function->PrintName(); |
| 8367 PrintF("]\n"); |
| 8368 } |
| 8369 function->ReplaceCode(function->shared()->code()); |
| 8368 } | 8370 } |
| 8369 it.Advance(); | |
| 8370 } | |
| 8371 | |
| 8372 if (!has_other_activations) { | |
| 8373 ActivationsFinder activations_finder(*function); | |
| 8374 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); | |
| 8375 has_other_activations = activations_finder.has_activations(); | |
| 8376 } | |
| 8377 | |
| 8378 if (!has_other_activations) { | |
| 8379 if (FLAG_trace_deopt) { | |
| 8380 PrintF("[removing optimized code for: "); | |
| 8381 function->PrintName(); | |
| 8382 PrintF("]\n"); | |
| 8383 } | |
| 8384 function->ReplaceCode(function->shared()->code()); | |
| 8385 } else { | 8371 } else { |
| 8372 // TODO(titzer): we should probably do DeoptimizeCodeList(code) |
| 8373 // unconditionally if the code is not already marked for deoptimization. |
| 8374 // If there is an index by shared function info, all the better. |
| 8386 Deoptimizer::DeoptimizeFunction(*function); | 8375 Deoptimizer::DeoptimizeFunction(*function); |
| 8387 } | 8376 } |
| 8388 // Evict optimized code for this function from the cache so that it doesn't | 8377 // Evict optimized code for this function from the cache so that it doesn't |
| 8389 // get used for new closures. | 8378 // get used for new closures. |
| 8390 function->shared()->EvictFromOptimizedCodeMap(*optimized_code, | 8379 function->shared()->EvictFromOptimizedCodeMap(*optimized_code, |
| 8391 "notify deoptimized"); | 8380 "notify deoptimized"); |
| 8392 | 8381 |
| 8393 return isolate->heap()->undefined_value(); | 8382 return isolate->heap()->undefined_value(); |
| 8394 } | 8383 } |
| 8395 | 8384 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8628 return Smi::FromInt(ast_id.ToInt()); | 8617 return Smi::FromInt(ast_id.ToInt()); |
| 8629 } else { | 8618 } else { |
| 8630 if (function->IsMarkedForLazyRecompilation()) { | 8619 if (function->IsMarkedForLazyRecompilation()) { |
| 8631 function->ReplaceCode(function->shared()->code()); | 8620 function->ReplaceCode(function->shared()->code()); |
| 8632 } | 8621 } |
| 8633 return Smi::FromInt(-1); | 8622 return Smi::FromInt(-1); |
| 8634 } | 8623 } |
| 8635 } | 8624 } |
| 8636 | 8625 |
| 8637 | 8626 |
| 8627 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) { |
| 8628 SealHandleScope shs(isolate); |
| 8629 ASSERT(args.length() == 2); |
| 8630 #ifdef DEBUG |
| 8631 CONVERT_SMI_ARG_CHECKED(interval, 0); |
| 8632 CONVERT_SMI_ARG_CHECKED(timeout, 1); |
| 8633 isolate->heap()->set_allocation_timeout(timeout); |
| 8634 FLAG_gc_interval = interval; |
| 8635 #endif |
| 8636 return isolate->heap()->undefined_value(); |
| 8637 } |
| 8638 |
| 8639 |
| 8638 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { | 8640 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { |
| 8639 SealHandleScope shs(isolate); | 8641 SealHandleScope shs(isolate); |
| 8640 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); | 8642 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); |
| 8641 return isolate->heap()->undefined_value(); | 8643 return isolate->heap()->undefined_value(); |
| 8642 } | 8644 } |
| 8643 | 8645 |
| 8644 | 8646 |
| 8645 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) { | 8647 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) { |
| 8646 SealHandleScope shs(isolate); | 8648 SealHandleScope shs(isolate); |
| 8647 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); | 8649 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); |
| (...skipping 4984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13632 | 13634 |
| 13633 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) { | 13635 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) { |
| 13634 HandleScope scope(isolate); | 13636 HandleScope scope(isolate); |
| 13635 | 13637 |
| 13636 ASSERT(args.length() == 2); | 13638 ASSERT(args.length() == 2); |
| 13637 | 13639 |
| 13638 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); | 13640 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); |
| 13639 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); | 13641 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); |
| 13640 | 13642 |
| 13641 bool has_pending_exception = false; | 13643 bool has_pending_exception = false; |
| 13642 double millis = Execution::ToNumber(date, &has_pending_exception)->Number(); | 13644 Handle<Object> value = Execution::ToNumber(date, &has_pending_exception); |
| 13643 if (has_pending_exception) { | 13645 if (has_pending_exception) { |
| 13644 ASSERT(isolate->has_pending_exception()); | 13646 ASSERT(isolate->has_pending_exception()); |
| 13645 return Failure::Exception(); | 13647 return Failure::Exception(); |
| 13646 } | 13648 } |
| 13647 | 13649 |
| 13648 icu::SimpleDateFormat* date_format = | 13650 icu::SimpleDateFormat* date_format = |
| 13649 DateFormat::UnpackDateFormat(isolate, date_format_holder); | 13651 DateFormat::UnpackDateFormat(isolate, date_format_holder); |
| 13650 if (!date_format) return isolate->ThrowIllegalOperation(); | 13652 if (!date_format) return isolate->ThrowIllegalOperation(); |
| 13651 | 13653 |
| 13652 icu::UnicodeString result; | 13654 icu::UnicodeString result; |
| 13653 date_format->format(millis, result); | 13655 date_format->format(value->Number(), result); |
| 13654 | 13656 |
| 13655 return *isolate->factory()->NewStringFromTwoByte( | 13657 return *isolate->factory()->NewStringFromTwoByte( |
| 13656 Vector<const uint16_t>( | 13658 Vector<const uint16_t>( |
| 13657 reinterpret_cast<const uint16_t*>(result.getBuffer()), | 13659 reinterpret_cast<const uint16_t*>(result.getBuffer()), |
| 13658 result.length())); | 13660 result.length())); |
| 13659 } | 13661 } |
| 13660 | 13662 |
| 13661 | 13663 |
| 13662 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) { | 13664 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) { |
| 13663 HandleScope scope(isolate); | 13665 HandleScope scope(isolate); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13736 | 13738 |
| 13737 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) { | 13739 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) { |
| 13738 HandleScope scope(isolate); | 13740 HandleScope scope(isolate); |
| 13739 | 13741 |
| 13740 ASSERT(args.length() == 2); | 13742 ASSERT(args.length() == 2); |
| 13741 | 13743 |
| 13742 CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0); | 13744 CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0); |
| 13743 CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); | 13745 CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); |
| 13744 | 13746 |
| 13745 bool has_pending_exception = false; | 13747 bool has_pending_exception = false; |
| 13746 double value = Execution::ToNumber(number, &has_pending_exception)->Number(); | 13748 Handle<Object> value = Execution::ToNumber(number, &has_pending_exception); |
| 13747 if (has_pending_exception) { | 13749 if (has_pending_exception) { |
| 13748 ASSERT(isolate->has_pending_exception()); | 13750 ASSERT(isolate->has_pending_exception()); |
| 13749 return Failure::Exception(); | 13751 return Failure::Exception(); |
| 13750 } | 13752 } |
| 13751 | 13753 |
| 13752 icu::DecimalFormat* number_format = | 13754 icu::DecimalFormat* number_format = |
| 13753 NumberFormat::UnpackNumberFormat(isolate, number_format_holder); | 13755 NumberFormat::UnpackNumberFormat(isolate, number_format_holder); |
| 13754 if (!number_format) return isolate->ThrowIllegalOperation(); | 13756 if (!number_format) return isolate->ThrowIllegalOperation(); |
| 13755 | 13757 |
| 13756 icu::UnicodeString result; | 13758 icu::UnicodeString result; |
| 13757 number_format->format(value, result); | 13759 number_format->format(value->Number(), result); |
| 13758 | 13760 |
| 13759 return *isolate->factory()->NewStringFromTwoByte( | 13761 return *isolate->factory()->NewStringFromTwoByte( |
| 13760 Vector<const uint16_t>( | 13762 Vector<const uint16_t>( |
| 13761 reinterpret_cast<const uint16_t*>(result.getBuffer()), | 13763 reinterpret_cast<const uint16_t*>(result.getBuffer()), |
| 13762 result.length())); | 13764 result.length())); |
| 13763 } | 13765 } |
| 13764 | 13766 |
| 13765 | 13767 |
| 13766 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) { | 13768 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) { |
| 13767 HandleScope scope(isolate); | 13769 HandleScope scope(isolate); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13986 | 13988 |
| 13987 RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) { | 13989 RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) { |
| 13988 HandleScope scope(isolate); | 13990 HandleScope scope(isolate); |
| 13989 ASSERT(args.length() == 1); | 13991 ASSERT(args.length() == 1); |
| 13990 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); | 13992 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); |
| 13991 FlattenString(str); | 13993 FlattenString(str); |
| 13992 return isolate->heap()->undefined_value(); | 13994 return isolate->heap()->undefined_value(); |
| 13993 } | 13995 } |
| 13994 | 13996 |
| 13995 | 13997 |
| 13998 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) { |
| 13999 HandleScope scope(isolate); |
| 14000 ASSERT(args.length() == 0); |
| 14001 isolate->heap()->NotifyContextDisposed(); |
| 14002 return isolate->heap()->undefined_value(); |
| 14003 } |
| 14004 |
| 14005 |
| 13996 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) { | 14006 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) { |
| 13997 HandleScope scope(isolate); | 14007 HandleScope scope(isolate); |
| 13998 ASSERT(args.length() == 1); | 14008 ASSERT(args.length() == 1); |
| 13999 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 14009 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
| 14000 if (!object->IsJSObject()) return Smi::FromInt(0); | 14010 if (!object->IsJSObject()) return Smi::FromInt(0); |
| 14001 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 14011 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 14002 if (!js_object->map()->is_deprecated()) return Smi::FromInt(0); | 14012 if (!js_object->map()->is_deprecated()) return Smi::FromInt(0); |
| 14003 JSObject::MigrateInstance(js_object); | 14013 JSObject::MigrateInstance(js_object); |
| 14004 return *object; | 14014 return *object; |
| 14005 } | 14015 } |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14481 // Handle last resort GC and make sure to allow future allocations | 14491 // Handle last resort GC and make sure to allow future allocations |
| 14482 // to grow the heap without causing GCs (if possible). | 14492 // to grow the heap without causing GCs (if possible). |
| 14483 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14493 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 14484 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14494 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14485 "Runtime::PerformGC"); | 14495 "Runtime::PerformGC"); |
| 14486 } | 14496 } |
| 14487 } | 14497 } |
| 14488 | 14498 |
| 14489 | 14499 |
| 14490 } } // namespace v8::internal | 14500 } } // namespace v8::internal |
| OLD | NEW |