| Index: src/liveedit.cc
|
| diff --git a/src/liveedit.cc b/src/liveedit.cc
|
| index b260c81f844be5bef478ff3b63d44797663f5385..c0da38cab7e3885fcc043215476a8b8d49a1499e 100644
|
| --- a/src/liveedit.cc
|
| +++ b/src/liveedit.cc
|
| @@ -631,8 +631,8 @@ static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) {
|
|
|
| // Wraps any object into a OpaqueReference, that will hide the object
|
| // from JavaScript.
|
| -static Handle<JSValue> WrapInJSValue(Handle<Object> object) {
|
| - Isolate* isolate = Isolate::Current();
|
| +static Handle<JSValue> WrapInJSValue(Handle<HeapObject> object) {
|
| + Isolate* isolate = object->GetIsolate();
|
| Handle<JSFunction> constructor = isolate->opaque_reference_function();
|
| Handle<JSValue> result =
|
| Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
|
| @@ -662,8 +662,8 @@ static int GetArrayLength(Handle<JSArray> array) {
|
| template<typename S>
|
| class JSArrayBasedStruct {
|
| public:
|
| - static S Create() {
|
| - Factory* factory = Isolate::Current()->factory();
|
| + static S Create(Isolate* isolate) {
|
| + Factory* factory = isolate->factory();
|
| Handle<JSArray> array = factory->NewJSArray(S::kSize_);
|
| return S(array);
|
| }
|
| @@ -691,7 +691,7 @@ class JSArrayBasedStruct {
|
| Handle<Smi>(Smi::FromInt(value), isolate()));
|
| }
|
| Object* GetField(int field_position) {
|
| - return array_->GetElementNoExceptionThrown(field_position);
|
| + return array_->GetElementNoExceptionThrown(isolate(), field_position);
|
| }
|
| int GetSmiValueField(int field_position) {
|
| Object* res = GetField(field_position);
|
| @@ -724,7 +724,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
| this->SetSmiValueField(kParentIndexOffset_, parent_index);
|
| }
|
| void SetFunctionCode(Handle<Code> function_code,
|
| - Handle<Object> code_scope_info) {
|
| + Handle<HeapObject> code_scope_info) {
|
| Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
|
| this->SetField(kCodeOffset_, code_wrapper);
|
|
|
| @@ -788,7 +788,8 @@ class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
|
| public:
|
| static bool IsInstance(Handle<JSArray> array) {
|
| return array->length() == Smi::FromInt(kSize_) &&
|
| - array->GetElementNoExceptionThrown(kSharedInfoOffset_)->IsJSValue();
|
| + array->GetElementNoExceptionThrown(
|
| + array->GetIsolate(), kSharedInfoOffset_)->IsJSValue();
|
| }
|
|
|
| explicit SharedInfoWrapper(Handle<JSArray> array)
|
| @@ -832,7 +833,7 @@ class FunctionInfoListener {
|
|
|
| void FunctionStarted(FunctionLiteral* fun) {
|
| HandleScope scope(isolate());
|
| - FunctionInfoWrapper info = FunctionInfoWrapper::Create();
|
| + FunctionInfoWrapper info = FunctionInfoWrapper::Create(isolate());
|
| info.SetInitialProperties(fun->name(), fun->start_position(),
|
| fun->end_position(), fun->parameter_count(),
|
| fun->materialized_literal_count(),
|
| @@ -846,7 +847,8 @@ class FunctionInfoListener {
|
| HandleScope scope(isolate());
|
| FunctionInfoWrapper info =
|
| FunctionInfoWrapper::cast(
|
| - result_->GetElementNoExceptionThrown(current_parent_index_));
|
| + result_->GetElementNoExceptionThrown(
|
| + isolate(), current_parent_index_));
|
| current_parent_index_ = info.GetParentIndex();
|
| }
|
|
|
| @@ -855,10 +857,10 @@ class FunctionInfoListener {
|
| void FunctionCode(Handle<Code> function_code) {
|
| FunctionInfoWrapper info =
|
| FunctionInfoWrapper::cast(
|
| - result_->GetElementNoExceptionThrown(current_parent_index_));
|
| + result_->GetElementNoExceptionThrown(
|
| + isolate(), current_parent_index_));
|
| info.SetFunctionCode(function_code,
|
| - Handle<Object>(isolate()->heap()->null_value(),
|
| - isolate()));
|
| + Handle<HeapObject>(isolate()->heap()->null_value()));
|
| }
|
|
|
| // Saves full information about a function: its code, its scope info
|
| @@ -870,9 +872,10 @@ class FunctionInfoListener {
|
| }
|
| FunctionInfoWrapper info =
|
| FunctionInfoWrapper::cast(
|
| - result_->GetElementNoExceptionThrown(current_parent_index_));
|
| + result_->GetElementNoExceptionThrown(
|
| + isolate(), current_parent_index_));
|
| info.SetFunctionCode(Handle<Code>(shared->code()),
|
| - Handle<Object>(shared->scope_info(), isolate()));
|
| + Handle<HeapObject>(shared->scope_info()));
|
| info.SetSharedFunctionInfo(shared);
|
|
|
| Handle<Object> scope_info_list(SerializeFunctionScope(scope, zone),
|
| @@ -935,7 +938,7 @@ class FunctionInfoListener {
|
|
|
| JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
|
| Handle<String> source) {
|
| - Isolate* isolate = Isolate::Current();
|
| + Isolate* isolate = script->GetIsolate();
|
|
|
| FunctionInfoListener listener(isolate);
|
| Handle<Object> original_source =
|
| @@ -1001,12 +1004,14 @@ JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
|
|
|
|
|
| void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
|
| - HandleScope scope(array->GetIsolate());
|
| + Isolate* isolate = array->GetIsolate();
|
| + HandleScope scope(isolate);
|
| int len = GetArrayLength(array);
|
| for (int i = 0; i < len; i++) {
|
| Handle<SharedFunctionInfo> info(
|
| - SharedFunctionInfo::cast(array->GetElementNoExceptionThrown(i)));
|
| - SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create();
|
| + SharedFunctionInfo::cast(
|
| + array->GetElementNoExceptionThrown(isolate, i)));
|
| + SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(isolate);
|
| Handle<String> name_handle(String::cast(info->name()));
|
| info_wrapper.SetProperties(name_handle, info->start_position(),
|
| info->end_position(), info);
|
| @@ -1242,34 +1247,48 @@ static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) {
|
| }
|
|
|
|
|
| -class DependentFunctionFilter : public OptimizedFunctionFilter {
|
| +// Marks code that shares the same shared function info or has inlined
|
| +// code that shares the same function info.
|
| +class DependentFunctionMarker: public OptimizedFunctionVisitor {
|
| public:
|
| - explicit DependentFunctionFilter(
|
| - SharedFunctionInfo* function_info)
|
| - : function_info_(function_info) {}
|
| -
|
| - virtual bool TakeFunction(JSFunction* function) {
|
| - return (function->shared() == function_info_ ||
|
| - IsInlined(function, function_info_));
|
| + SharedFunctionInfo* shared_info_;
|
| + bool found_;
|
| +
|
| + explicit DependentFunctionMarker(SharedFunctionInfo* shared_info)
|
| + : shared_info_(shared_info), found_(false) { }
|
| +
|
| + virtual void EnterContext(Context* context) { } // Don't care.
|
| + virtual void LeaveContext(Context* context) { } // Don't care.
|
| + virtual void VisitFunction(JSFunction* function) {
|
| + // It should be guaranteed by the iterator that everything is optimized.
|
| + ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
|
| + if (shared_info_ == function->shared() ||
|
| + IsInlined(function, shared_info_)) {
|
| + // Mark the code for deoptimization.
|
| + function->code()->set_marked_for_deoptimization(true);
|
| + found_ = true;
|
| + }
|
| }
|
| -
|
| - private:
|
| - SharedFunctionInfo* function_info_;
|
| };
|
|
|
|
|
| static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) {
|
| DisallowHeapAllocation no_allocation;
|
| + DependentFunctionMarker marker(function_info);
|
| + // TODO(titzer): need to traverse all optimized code to find OSR code here.
|
| + Deoptimizer::VisitAllOptimizedFunctions(function_info->GetIsolate(), &marker);
|
|
|
| - DependentFunctionFilter filter(function_info);
|
| - Deoptimizer::DeoptimizeAllFunctionsWith(function_info->GetIsolate(), &filter);
|
| + if (marker.found_) {
|
| + // Only go through with the deoptimization if something was found.
|
| + Deoptimizer::DeoptimizeMarkedCode(function_info->GetIsolate());
|
| + }
|
| }
|
|
|
|
|
| MaybeObject* LiveEdit::ReplaceFunctionCode(
|
| Handle<JSArray> new_compile_info_array,
|
| Handle<JSArray> shared_info_array) {
|
| - Isolate* isolate = Isolate::Current();
|
| + Isolate* isolate = new_compile_info_array->GetIsolate();
|
| HandleScope scope(isolate);
|
|
|
| if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
|
| @@ -1343,7 +1362,7 @@ void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
|
| CHECK(script_handle->IsScript() || script_handle->IsUndefined());
|
| shared_info->set_script(*script_handle);
|
|
|
| - Isolate::Current()->compilation_cache()->Remove(shared_info);
|
| + function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info);
|
| }
|
|
|
|
|
| @@ -1360,20 +1379,24 @@ static int TranslatePosition(int original_position,
|
| Handle<JSArray> position_change_array) {
|
| int position_diff = 0;
|
| int array_len = GetArrayLength(position_change_array);
|
| + Isolate* isolate = position_change_array->GetIsolate();
|
| // TODO(635): binary search may be used here
|
| for (int i = 0; i < array_len; i += 3) {
|
| - Object* element = position_change_array->GetElementNoExceptionThrown(i);
|
| + Object* element =
|
| + position_change_array->GetElementNoExceptionThrown(isolate, i);
|
| CHECK(element->IsSmi());
|
| int chunk_start = Smi::cast(element)->value();
|
| if (original_position < chunk_start) {
|
| break;
|
| }
|
| - element = position_change_array->GetElementNoExceptionThrown(i + 1);
|
| + element = position_change_array->GetElementNoExceptionThrown(isolate,
|
| + i + 1);
|
| CHECK(element->IsSmi());
|
| int chunk_end = Smi::cast(element)->value();
|
| // Position mustn't be inside a chunk.
|
| ASSERT(original_position >= chunk_end);
|
| - element = position_change_array->GetElementNoExceptionThrown(i + 2);
|
| + element = position_change_array->GetElementNoExceptionThrown(isolate,
|
| + i + 2);
|
| CHECK(element->IsSmi());
|
| int chunk_changed_end = Smi::cast(element)->value();
|
| position_diff = chunk_changed_end - chunk_end;
|
| @@ -1508,7 +1531,7 @@ static Handle<Code> PatchPositionsInCode(
|
| MaybeObject* LiveEdit::PatchFunctionPositions(
|
| Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) {
|
| if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
|
| - return Isolate::Current()->ThrowIllegalOperation();
|
| + return shared_info_array->GetIsolate()->ThrowIllegalOperation();
|
| }
|
|
|
| SharedInfoWrapper shared_info_wrapper(shared_info_array);
|
| @@ -1630,7 +1653,8 @@ static bool CheckActivation(Handle<JSArray> shared_info_array,
|
| Isolate* isolate = shared_info_array->GetIsolate();
|
| int len = GetArrayLength(shared_info_array);
|
| for (int i = 0; i < len; i++) {
|
| - Object* element = shared_info_array->GetElementNoExceptionThrown(i);
|
| + Object* element =
|
| + shared_info_array->GetElementNoExceptionThrown(isolate, i);
|
| CHECK(element->IsJSValue());
|
| Handle<JSValue> jsvalue(JSValue::cast(element));
|
| Handle<SharedFunctionInfo> shared =
|
| @@ -1651,7 +1675,7 @@ static bool CheckActivation(Handle<JSArray> shared_info_array,
|
| static bool FixTryCatchHandler(StackFrame* top_frame,
|
| StackFrame* bottom_frame) {
|
| Address* pointer_address =
|
| - &Memory::Address_at(Isolate::Current()->get_address_from_id(
|
| + &Memory::Address_at(top_frame->isolate()->get_address_from_id(
|
| Isolate::kHandlerAddress));
|
|
|
| while (*pointer_address < top_frame->sp()) {
|
| @@ -1687,7 +1711,7 @@ static const char* DropFrames(Vector<StackFrame*> frames,
|
| ASSERT(bottom_js_frame->is_java_script());
|
|
|
| // Check the nature of the top frame.
|
| - Isolate* isolate = Isolate::Current();
|
| + Isolate* isolate = bottom_js_frame->isolate();
|
| Code* pre_top_frame_code = pre_top_frame->LookupCode();
|
| bool frame_has_padding;
|
| if (pre_top_frame_code->is_inline_cache_stub() &&
|
| @@ -1790,7 +1814,7 @@ static const char* DropFrames(Vector<StackFrame*> frames,
|
| // Make sure FixTryCatchHandler is idempotent.
|
| ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
|
|
|
| - Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit();
|
| + Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit();
|
| *top_frame_pc_address = code->entry();
|
| pre_top_frame->SetCallerFp(bottom_js_frame->fp());
|
|
|
| @@ -1838,8 +1862,7 @@ class MultipleFunctionTarget {
|
| // Drops all call frame matched by target and all frames above them.
|
| template<typename TARGET>
|
| static const char* DropActivationsInActiveThreadImpl(
|
| - TARGET& target, bool do_drop) {
|
| - Isolate* isolate = Isolate::Current();
|
| + Isolate* isolate, TARGET& target, bool do_drop) {
|
| Debug* debug = isolate->debug();
|
| Zone zone(isolate);
|
| Vector<StackFrame*> frames = CreateStackMap(isolate, &zone);
|
| @@ -1938,8 +1961,8 @@ static const char* DropActivationsInActiveThread(
|
| Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) {
|
| MultipleFunctionTarget target(shared_info_array, result);
|
|
|
| - const char* message =
|
| - DropActivationsInActiveThreadImpl(target, do_drop);
|
| + const char* message = DropActivationsInActiveThreadImpl(
|
| + shared_info_array->GetIsolate(), target, do_drop);
|
| if (message) {
|
| return message;
|
| }
|
| @@ -1949,7 +1972,7 @@ static const char* DropActivationsInActiveThread(
|
|
|
| // Replace "blocked on active" with "replaced on active" status.
|
| for (int i = 0; i < array_len; i++) {
|
| - if (result->GetElement(i) ==
|
| + if (result->GetElement(result->GetIsolate(), i) ==
|
| Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
|
| Handle<Object> replaced(
|
| Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
|
| @@ -2004,7 +2027,7 @@ Handle<JSArray> LiveEdit::CheckAndDropActivations(
|
| // First check inactive threads. Fail if some functions are blocked there.
|
| InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array,
|
| result);
|
| - Isolate::Current()->thread_manager()->IterateArchivedThreads(
|
| + isolate->thread_manager()->IterateArchivedThreads(
|
| &inactive_threads_checker);
|
| if (inactive_threads_checker.HasBlockedFunctions()) {
|
| return result;
|
| @@ -2056,7 +2079,8 @@ class SingleFrameTarget {
|
| const char* LiveEdit::RestartFrame(JavaScriptFrame* frame) {
|
| SingleFrameTarget target(frame);
|
|
|
| - const char* result = DropActivationsInActiveThreadImpl(target, true);
|
| + const char* result = DropActivationsInActiveThreadImpl(
|
| + frame->isolate(), target, true);
|
| if (result != NULL) {
|
| return result;
|
| }
|
|
|