1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/background-parsing-task.h"
6
7#include "src/objects-inl.h"
8#include "src/parsing/parser.h"
9
10namespace v8 {
11namespace internal {
12
13void StreamedSource::Release() {
14  parser.reset();
15  info.reset();
16}
17
18BackgroundParsingTask::BackgroundParsingTask(
19    StreamedSource* source, ScriptCompiler::CompileOptions options,
20    int stack_size, Isolate* isolate)
21    : source_(source), stack_size_(stack_size), script_data_(nullptr) {
22  // We don't set the context to the CompilationInfo yet, because the background
23  // thread cannot do anything with it anyway. We set it just before compilation
24  // on the foreground thread.
25  DCHECK(options == ScriptCompiler::kProduceParserCache ||
26         options == ScriptCompiler::kProduceCodeCache ||
27         options == ScriptCompiler::kNoCompileOptions);
28
29  // Prepare the data for the internalization phase and compilation phase, which
30  // will happen in the main thread after parsing.
31  ParseInfo* info = new ParseInfo(isolate->allocator());
32  info->set_toplevel();
33  source->info.reset(info);
34  info->set_isolate(isolate);
35  info->set_source_stream(source->source_stream.get());
36  info->set_source_stream_encoding(source->encoding);
37  info->set_hash_seed(isolate->heap()->HashSeed());
38  info->set_unicode_cache(&source_->unicode_cache);
39  info->set_compile_options(options);
40  info->set_allow_lazy_parsing();
41
42  source_->info->set_cached_data(&script_data_);
43  // Parser needs to stay alive for finalizing the parsing on the main
44  // thread.
45  source_->parser.reset(new Parser(source_->info.get()));
46  source_->parser->DeserializeScopeChain(source_->info.get(),
47                                         MaybeHandle<ScopeInfo>());
48}
49
50
51void BackgroundParsingTask::Run() {
52  DisallowHeapAllocation no_allocation;
53  DisallowHandleAllocation no_handles;
54  DisallowHandleDereference no_deref;
55
56  // Reset the stack limit of the parser to reflect correctly that we're on a
57  // background thread.
58  uintptr_t stack_limit = GetCurrentStackPosition() - stack_size_ * KB;
59  source_->parser->set_stack_limit(stack_limit);
60
61  // Nullify the Isolate temporarily so that the background parser doesn't
62  // accidentally use it.
63  Isolate* isolate = source_->info->isolate();
64  source_->info->set_isolate(nullptr);
65
66  source_->parser->ParseOnBackground(source_->info.get());
67
68  if (script_data_ != nullptr) {
69    source_->cached_data.reset(new ScriptCompiler::CachedData(
70        script_data_->data(), script_data_->length(),
71        ScriptCompiler::CachedData::BufferOwned));
72    script_data_->ReleaseDataOwnership();
73    delete script_data_;
74    script_data_ = nullptr;
75  }
76  source_->info->set_isolate(isolate);
77}
78}  // namespace internal
79}  // namespace v8
80