Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 7a76121e887425056e188c310640229b1d52b550..d46fadcf0fddae25fcc52e4195f370691fec81a1 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -13641,55 +13641,63 @@ Handle<JSObject> Script::GetWrapper(Handle<Script> script) { |
| return result; |
| } |
| - |
| MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo( |
| - FunctionLiteral* fun) { |
| - WeakFixedArray::Iterator iterator(shared_function_infos()); |
| - SharedFunctionInfo* shared; |
| - while ((shared = iterator.Next<SharedFunctionInfo>())) { |
| - if (fun->function_token_position() == shared->function_token_position() && |
| - fun->start_position() == shared->start_position() && |
| - fun->end_position() == shared->end_position()) { |
| - DCHECK_EQ(fun->function_literal_id(), shared->function_literal_id()); |
| - return Handle<SharedFunctionInfo>(shared); |
| - } |
| - DCHECK_NE(fun->function_literal_id(), shared->function_literal_id()); |
| + Isolate* isolate, FunctionLiteral* fun) { |
| + DCHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid); |
| + DCHECK_LT(fun->function_literal_id(), shared_function_infos()->length()); |
| + Object* shared = shared_function_infos()->get(fun->function_literal_id()); |
| + if (shared->IsUndefined(isolate) || WeakCell::cast(shared)->cleared()) { |
| + return MaybeHandle<SharedFunctionInfo>(); |
| } |
| - return MaybeHandle<SharedFunctionInfo>(); |
| + return handle(SharedFunctionInfo::cast(WeakCell::cast(shared)->value())); |
| } |
| - |
| Script::Iterator::Iterator(Isolate* isolate) |
| : iterator_(isolate->heap()->script_list()) {} |
| Script* Script::Iterator::Next() { return iterator_.Next<Script>(); } |
| +SharedFunctionInfo::ScriptIterator::ScriptIterator(Handle<Script> script) |
| + : script_(script), index_(0) {} |
| -SharedFunctionInfo::Iterator::Iterator(Isolate* isolate) |
| - : script_iterator_(isolate), |
| - sfi_iterator_(isolate->heap()->noscript_shared_function_infos()) {} |
| - |
| +SharedFunctionInfo* SharedFunctionInfo::ScriptIterator::Next() { |
| + Isolate* isolate = script_->GetIsolate(); |
|
Toon Verwaest
2016/12/08 07:31:31
What about just stashing isolate and shared_functi
jochen (gone - plz use gerrit)
2016/12/08 12:31:14
done
|
| + FixedArray* list = script_->shared_function_infos(); |
| + while (index_ < list->length()) { |
| + Object* raw = list->get(index_++); |
| + if (raw->IsUndefined(isolate) || WeakCell::cast(raw)->cleared()) continue; |
| + return SharedFunctionInfo::cast(WeakCell::cast(raw)->value()); |
| + } |
| + return nullptr; |
| +} |
| -bool SharedFunctionInfo::Iterator::NextScript() { |
| - Script* script = script_iterator_.Next(); |
| - if (script == NULL) return false; |
| - sfi_iterator_.Reset(script->shared_function_infos()); |
| - return true; |
| +void SharedFunctionInfo::ScriptIterator::Reset(Handle<Script> script) { |
| + script_ = script; |
| + index_ = 0; |
| } |
| +SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate) |
| + : script_iterator_(isolate), |
| + noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()), |
| + sfi_iterator_(handle(script_iterator_.Next(), isolate)) {} |
| -SharedFunctionInfo* SharedFunctionInfo::Iterator::Next() { |
| - do { |
| - SharedFunctionInfo* next = sfi_iterator_.Next<SharedFunctionInfo>(); |
| - if (next != NULL) return next; |
| - } while (NextScript()); |
| - return NULL; |
| +SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() { |
| + SharedFunctionInfo* next = noscript_sfi_iterator_.Next<SharedFunctionInfo>(); |
| + if (next != nullptr) return next; |
| + for (;;) { |
| + next = sfi_iterator_.Next(); |
| + if (next != nullptr) return next; |
| + Script* next_script = script_iterator_.Next(); |
| + if (next_script == nullptr) return nullptr; |
| + sfi_iterator_.Reset(handle(next_script)); |
| + } |
| } |
| void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, |
| Handle<Object> script_object) { |
| + DCHECK_NE(shared->function_literal_id(), FunctionLiteral::kIdTypeInvalid); |
| if (shared->script() == *script_object) return; |
| Isolate* isolate = shared->GetIsolate(); |
| @@ -13697,39 +13705,52 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, |
| // the shared function info may be temporarily in two lists. |
| // This is okay because the gc-time processing of these lists can tolerate |
| // duplicates. |
| - Handle<Object> list; |
| if (script_object->IsScript()) { |
| Handle<Script> script = Handle<Script>::cast(script_object); |
| - list = handle(script->shared_function_infos(), isolate); |
| + Handle<FixedArray> list = handle(script->shared_function_infos(), isolate); |
| +#ifdef DEBUG |
| + DCHECK_LT(shared->function_literal_id(), list->length()); |
| + if (list->get(shared->function_literal_id())->IsWeakCell() && |
| + !WeakCell::cast(list->get(shared->function_literal_id()))->cleared()) { |
| + DCHECK( |
| + WeakCell::cast(list->get(shared->function_literal_id()))->value() == |
| + *shared); |
| + } |
| +#endif |
| + Handle<WeakCell> cell = isolate->factory()->NewWeakCell(shared); |
| + list->set(shared->function_literal_id(), *cell); |
| } else { |
| - list = isolate->factory()->noscript_shared_function_infos(); |
| - } |
| + Handle<Object> list = isolate->factory()->noscript_shared_function_infos(); |
| #ifdef DEBUG |
| - if (FLAG_enable_slow_asserts) { |
| - WeakFixedArray::Iterator iterator(*list); |
| - SharedFunctionInfo* next; |
| - while ((next = iterator.Next<SharedFunctionInfo>())) { |
| - DCHECK_NE(next, *shared); |
| + if (FLAG_enable_slow_asserts) { |
| + WeakFixedArray::Iterator iterator(*list); |
| + SharedFunctionInfo* next; |
| + while ((next = iterator.Next<SharedFunctionInfo>())) { |
| + DCHECK_NE(next, *shared); |
| + } |
| } |
| - } |
| #endif // DEBUG |
| - list = WeakFixedArray::Add(list, shared); |
| - if (script_object->IsScript()) { |
| - Handle<Script> script = Handle<Script>::cast(script_object); |
| - script->set_shared_function_infos(*list); |
| - } else { |
| + list = WeakFixedArray::Add(list, shared); |
| + |
| isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list); |
| } |
| - // Remove shared function info from old script's list. |
| if (shared->script()->IsScript()) { |
| + // Remove shared function info from old script's list. |
| Script* old_script = Script::cast(shared->script()); |
| - if (old_script->shared_function_infos()->IsWeakFixedArray()) { |
| - WeakFixedArray* list = |
| - WeakFixedArray::cast(old_script->shared_function_infos()); |
| - list->Remove(shared); |
| + |
| + // Due to liveedit, it might happen that the old_script doesn't know |
| + // about the SharedFunctionInfo, so we have to guard against that. |
| + Handle<FixedArray> infos(old_script->shared_function_infos(), isolate); |
| + if (shared->function_literal_id() < infos->length()) { |
| + Object* raw = old_script->shared_function_infos()->get( |
| + shared->function_literal_id()); |
| + if (!raw->IsWeakCell() || WeakCell::cast(raw)->value() == *shared) { |
| + old_script->shared_function_infos()->set( |
| + shared->function_literal_id(), isolate->heap()->undefined_value()); |
| + } |
| } |
| } else { |
| // Remove shared function info from root array. |
| @@ -13994,7 +14015,6 @@ void SharedFunctionInfo::InitFromFunctionLiteral( |
| shared_info->set_uses_arguments(lit->scope()->arguments() != NULL); |
| shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); |
| shared_info->set_is_function(lit->is_function()); |
| - shared_info->set_never_compiled(true); |
| shared_info->set_kind(lit->kind()); |
| if (!IsConstructable(lit->kind(), lit->language_mode())) { |
| shared_info->SetConstructStub( |