diff options
| author | Ben Murdoch <benm@google.com> | 2011-05-05 13:52:32 +0100 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2011-05-10 15:41:47 +0100 |
| commit | b0fe1620dcb4135ac3ab2d66ff93072373911299 (patch) | |
| tree | 3487cdc7e01ec56a6f84ea20f4bae596a0b73986 /src/liveedit.cc | |
| parent | df5bff59602802b769e994b0dc1d8869a27fa40c (diff) | |
| download | android_external_v8-b0fe1620dcb4135ac3ab2d66ff93072373911299.tar.gz android_external_v8-b0fe1620dcb4135ac3ab2d66ff93072373911299.tar.bz2 android_external_v8-b0fe1620dcb4135ac3ab2d66ff93072373911299.zip | |
Update V8 to r6101 as required by WebKit r74534
Change-Id: I7f84af8dd732f11898fd644b2c2b1538914cb78d
Diffstat (limited to 'src/liveedit.cc')
| -rw-r--r-- | src/liveedit.cc | 113 |
1 files changed, 97 insertions, 16 deletions
diff --git a/src/liveedit.cc b/src/liveedit.cc index 642b3e6a..c4cb68e7 100644 --- a/src/liveedit.cc +++ b/src/liveedit.cc @@ -31,7 +31,9 @@ #include "liveedit.h" #include "compiler.h" +#include "compilation-cache.h" #include "debug.h" +#include "deoptimizer.h" #include "global-handles.h" #include "memory.h" #include "oprofile-agent.h" @@ -605,18 +607,18 @@ class FunctionInfoListener { void FunctionDone() { HandleScope scope; - Object* element = - result_->GetElementNoExceptionThrown(current_parent_index_); - FunctionInfoWrapper info = FunctionInfoWrapper::cast(element); + FunctionInfoWrapper info = + FunctionInfoWrapper::cast( + result_->GetElementNoExceptionThrown(current_parent_index_)); current_parent_index_ = info.GetParentIndex(); } // Saves only function code, because for a script function we // may never create a SharedFunctionInfo object. void FunctionCode(Handle<Code> function_code) { - Object* element = - result_->GetElementNoExceptionThrown(current_parent_index_); - FunctionInfoWrapper info = FunctionInfoWrapper::cast(element); + FunctionInfoWrapper info = + FunctionInfoWrapper::cast( + result_->GetElementNoExceptionThrown(current_parent_index_)); info.SetFunctionCode(function_code, Handle<Object>(Heap::null_value())); } @@ -626,9 +628,9 @@ class FunctionInfoListener { if (!shared->IsSharedFunctionInfo()) { return; } - Object* element = - result_->GetElementNoExceptionThrown(current_parent_index_); - FunctionInfoWrapper info = FunctionInfoWrapper::cast(element); + FunctionInfoWrapper info = + FunctionInfoWrapper::cast( + result_->GetElementNoExceptionThrown(current_parent_index_)); info.SetFunctionCode(Handle<Code>(shared->code()), Handle<Object>(shared->scope_info())); info.SetSharedFunctionInfo(shared); @@ -828,6 +830,61 @@ static bool IsJSFunctionCode(Code* code) { } +// Returns true if an instance of candidate were inlined into function's code. +static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { + AssertNoAllocation no_gc; + + if (function->code()->kind() != Code::OPTIMIZED_FUNCTION) return false; + + DeoptimizationInputData* data = + DeoptimizationInputData::cast(function->code()->deoptimization_data()); + + if (data == Heap::empty_fixed_array()) return false; + + FixedArray* literals = data->LiteralArray(); + + int inlined_count = data->InlinedFunctionCount()->value(); + for (int i = 0; i < inlined_count; ++i) { + JSFunction* inlined = JSFunction::cast(literals->get(i)); + if (inlined->shared() == candidate) return true; + } + + return false; +} + + +class DependentFunctionsDeoptimizingVisitor : public OptimizedFunctionVisitor { + public: + explicit DependentFunctionsDeoptimizingVisitor( + SharedFunctionInfo* function_info) + : function_info_(function_info) {} + + virtual void EnterContext(Context* context) { + } + + virtual void VisitFunction(JSFunction* function) { + if (function->shared() == function_info_ || + IsInlined(function, function_info_)) { + Deoptimizer::DeoptimizeFunction(function); + } + } + + virtual void LeaveContext(Context* context) { + } + + private: + SharedFunctionInfo* function_info_; +}; + + +static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) { + AssertNoAllocation no_allocation; + + DependentFunctionsDeoptimizingVisitor visitor(function_info); + Deoptimizer::VisitAllOptimizedFunctions(&visitor); +} + + MaybeObject* LiveEdit::ReplaceFunctionCode( Handle<JSArray> new_compile_info_array, Handle<JSArray> shared_info_array) { @@ -864,17 +921,38 @@ MaybeObject* LiveEdit::ReplaceFunctionCode( shared_info->set_construct_stub( Builtins::builtin(Builtins::JSConstructStubGeneric)); + DeoptimizeDependentFunctions(*shared_info); + CompilationCache::Remove(shared_info); + + return Heap::undefined_value(); +} + + +MaybeObject* LiveEdit::FunctionSourceUpdated( + Handle<JSArray> shared_info_array) { + HandleScope scope; + + if (!SharedInfoWrapper::IsInstance(shared_info_array)) { + return Top::ThrowIllegalOperation(); + } + + SharedInfoWrapper shared_info_wrapper(shared_info_array); + Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); + + DeoptimizeDependentFunctions(*shared_info); + CompilationCache::Remove(shared_info); + return Heap::undefined_value(); } -// TODO(635): Eval caches its scripts (same text -- same compiled info). -// Make sure we clear such caches. void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, Handle<Object> script_handle) { Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(UnwrapJSValue(function_wrapper)); shared_info->set_script(*script_handle); + + CompilationCache::Remove(shared_info); } @@ -1135,11 +1213,14 @@ void LiveEdit::ReplaceRefToNestedFunction( // Check an activation against list of functions. If there is a function // that matches, its status in result array is changed to status argument value. static bool CheckActivation(Handle<JSArray> shared_info_array, - Handle<JSArray> result, StackFrame* frame, + Handle<JSArray> result, + StackFrame* frame, LiveEdit::FunctionPatchabilityStatus status) { - if (!frame->is_java_script()) { - return false; - } + if (!frame->is_java_script()) return false; + + Handle<JSFunction> function( + JSFunction::cast(JavaScriptFrame::cast(frame)->function())); + int len = Smi::cast(shared_info_array->length())->value(); for (int i = 0; i < len; i++) { JSValue* wrapper = @@ -1147,7 +1228,7 @@ static bool CheckActivation(Handle<JSArray> shared_info_array, Handle<SharedFunctionInfo> shared( SharedFunctionInfo::cast(wrapper->value())); - if (frame->code() == shared->code()) { + if (function->shared() == *shared || IsInlined(*function, *shared)) { SetElement(result, i, Handle<Smi>(Smi::FromInt(status))); return true; } |
