Revert "Keep a canonical list of shared function infos."
Speculative revert in the hopes of fixing serializer crashes seen in canary. This reverts commitc166945083
, as well as followup change "Do not look for existing shared function info when compiling a new script." (commit7c43967bb7
). BUG=chromium:503552,v8:4132 TBR=yangguo@chromium.org LOG=n Review URL: https://codereview.chromium.org/1207583002 Cr-Commit-Position: refs/heads/master@{#29241}
This commit is contained in:
parent
57306b59e8
commit
3164aa7483
@ -933,7 +933,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -931,7 +931,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
19
src/ast.cc
19
src/ast.cc
@ -241,6 +241,25 @@ bool FunctionLiteral::NeedsHomeObject(Expression* expr) {
|
||||
}
|
||||
|
||||
|
||||
// Helper to find an existing shared function info in the baseline code for the
|
||||
// given function literal. Used to canonicalize SharedFunctionInfo objects.
|
||||
void FunctionLiteral::InitializeSharedInfo(
|
||||
Handle<Code> unoptimized_code) {
|
||||
for (RelocIterator it(*unoptimized_code); !it.done(); it.next()) {
|
||||
RelocInfo* rinfo = it.rinfo();
|
||||
if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
|
||||
Object* obj = rinfo->target_object();
|
||||
if (obj->IsSharedFunctionInfo()) {
|
||||
SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
|
||||
if (shared->start_position() == start_position()) {
|
||||
shared_info_ = Handle<SharedFunctionInfo>(shared);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
|
||||
Kind kind, bool is_static,
|
||||
bool is_computed_name)
|
||||
|
@ -2512,6 +2512,8 @@ class FunctionLiteral final : public Expression {
|
||||
bool AllowsLazyCompilation();
|
||||
bool AllowsLazyCompilationWithoutContext();
|
||||
|
||||
void InitializeSharedInfo(Handle<Code> code);
|
||||
|
||||
Handle<String> debug_name() const {
|
||||
if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
|
||||
return raw_name_->string();
|
||||
@ -2546,6 +2548,9 @@ class FunctionLiteral final : public Expression {
|
||||
inferred_name_ = Handle<String>();
|
||||
}
|
||||
|
||||
// shared_info may be null if it's not cached in full code.
|
||||
Handle<SharedFunctionInfo> shared_info() { return shared_info_; }
|
||||
|
||||
bool pretenure() { return Pretenure::decode(bitfield_); }
|
||||
void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
|
||||
|
||||
@ -2627,6 +2632,7 @@ class FunctionLiteral final : public Expression {
|
||||
private:
|
||||
const AstRawString* raw_name_;
|
||||
Handle<String> name_;
|
||||
Handle<SharedFunctionInfo> shared_info_;
|
||||
Scope* scope_;
|
||||
ZoneList<Statement*>* body_;
|
||||
const AstString* raw_inferred_name_;
|
||||
|
@ -563,10 +563,10 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
|
||||
Handle<String> source = factory->NewStringFromStaticChars("() {}");
|
||||
Handle<Script> script = factory->NewScript(source);
|
||||
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
|
||||
empty_function->shared()->set_script(*script);
|
||||
empty_function->shared()->set_start_position(0);
|
||||
empty_function->shared()->set_end_position(source->length());
|
||||
empty_function->shared()->DontAdaptArguments();
|
||||
SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
|
||||
|
||||
// Set prototypes for the function maps.
|
||||
Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
|
||||
|
@ -32,6 +32,7 @@
|
||||
// ~CodeGenerator
|
||||
// Generate
|
||||
// ComputeLazyCompile
|
||||
// BuildFunctionInfo
|
||||
// ProcessDeclarations
|
||||
// DeclareGlobals
|
||||
// CheckForInlineRuntimeCall
|
||||
|
@ -1015,9 +1015,6 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
|
||||
PostponeInterruptsScope postpone(info.isolate());
|
||||
VMState<COMPILER> state(info.isolate());
|
||||
|
||||
// Get rid of old list of shared function infos.
|
||||
script->set_shared_function_infos(Smi::FromInt(0));
|
||||
|
||||
info.parse_info()->set_global();
|
||||
if (!Parser::ParseStatic(info.parse_info())) return;
|
||||
|
||||
@ -1078,8 +1075,6 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
}
|
||||
}
|
||||
|
||||
info->MarkAsNewScript();
|
||||
|
||||
FunctionLiteral* lit = info->function();
|
||||
LiveEditFunctionTracker live_edit_tracker(isolate, lit);
|
||||
|
||||
@ -1106,7 +1101,7 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
|
||||
DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
|
||||
SharedFunctionInfo::InitFromFunctionLiteral(result, lit);
|
||||
SharedFunctionInfo::SetScript(result, script);
|
||||
result->set_script(*script);
|
||||
result->set_is_toplevel(true);
|
||||
|
||||
Handle<String> script_name = script->name()->IsString()
|
||||
@ -1336,25 +1331,10 @@ Handle<SharedFunctionInfo> Compiler::CompileStreamedScript(
|
||||
}
|
||||
|
||||
|
||||
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(
|
||||
FunctionLiteral* literal, Handle<Script> script,
|
||||
CompilationInfo* outer_info) {
|
||||
// Precondition: code has been parsed and scopes have been analyzed.
|
||||
MaybeHandle<SharedFunctionInfo> maybe_existing;
|
||||
if (outer_info->is_new_script()) {
|
||||
// There is no existing shared function info when compiling a new script.
|
||||
DCHECK(script->FindSharedFunctionInfo(literal).is_null());
|
||||
} else {
|
||||
maybe_existing = script->FindSharedFunctionInfo(literal);
|
||||
}
|
||||
// We found an existing shared function info. If it's already compiled,
|
||||
// don't worry about compiling it, and simply return it. If it's not yet
|
||||
// compiled, continue to decide whether to eagerly compile.
|
||||
Handle<SharedFunctionInfo> existing;
|
||||
if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
Zone zone;
|
||||
ParseInfo parse_info(&zone, script);
|
||||
CompilationInfo info(&parse_info);
|
||||
@ -1362,7 +1342,6 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
parse_info.set_scope(literal->scope());
|
||||
parse_info.set_language_mode(literal->scope()->language_mode());
|
||||
if (outer_info->will_serialize()) info.PrepareForSerializing();
|
||||
if (outer_info->is_new_script()) info.MarkAsNewScript();
|
||||
|
||||
Isolate* isolate = info.isolate();
|
||||
Factory* factory = isolate->factory();
|
||||
@ -1416,34 +1395,25 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
return Handle<SharedFunctionInfo>::null();
|
||||
}
|
||||
|
||||
if (maybe_existing.is_null()) {
|
||||
// Create a shared function info object.
|
||||
Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo(
|
||||
literal->name(), literal->materialized_literal_count(), literal->kind(),
|
||||
info.code(), scope_info, info.feedback_vector());
|
||||
// Create a shared function info object.
|
||||
Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo(
|
||||
literal->name(), literal->materialized_literal_count(), literal->kind(),
|
||||
info.code(), scope_info, info.feedback_vector());
|
||||
|
||||
SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
|
||||
SharedFunctionInfo::SetScript(result, script);
|
||||
result->set_is_toplevel(false);
|
||||
SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
|
||||
result->set_script(*script);
|
||||
result->set_is_toplevel(false);
|
||||
|
||||
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
|
||||
result->set_allows_lazy_compilation(literal->AllowsLazyCompilation());
|
||||
result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
|
||||
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
|
||||
result->set_allows_lazy_compilation(literal->AllowsLazyCompilation());
|
||||
result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
|
||||
|
||||
// Set the expected number of properties for instances and return
|
||||
// the resulting function.
|
||||
SetExpectedNofPropertiesFromEstimate(result,
|
||||
literal->expected_property_count());
|
||||
live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
|
||||
return result;
|
||||
} else {
|
||||
// We may have additional data from compilation now.
|
||||
DCHECK(!existing->is_compiled());
|
||||
existing->ReplaceCode(*info.code());
|
||||
existing->set_scope_info(*scope_info);
|
||||
existing->set_feedback_vector(*info.feedback_vector());
|
||||
return existing;
|
||||
}
|
||||
// Set the expected number of properties for instances and return
|
||||
// the resulting function.
|
||||
SetExpectedNofPropertiesFromEstimate(result,
|
||||
literal->expected_property_count());
|
||||
live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,8 +127,7 @@ class CompilationInfo {
|
||||
kSplittingEnabled = 1 << 13,
|
||||
kTypeFeedbackEnabled = 1 << 14,
|
||||
kDeoptimizationEnabled = 1 << 15,
|
||||
kSourcePositionsEnabled = 1 << 16,
|
||||
kNewScript = 1 << 17,
|
||||
kSourcePositionsEnabled = 1 << 16
|
||||
};
|
||||
|
||||
explicit CompilationInfo(ParseInfo* parse_info);
|
||||
@ -246,10 +245,6 @@ class CompilationInfo {
|
||||
|
||||
bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
|
||||
|
||||
void MarkAsNewScript() { SetFlag(kNewScript); }
|
||||
|
||||
bool is_new_script() const { return GetFlag(kNewScript); }
|
||||
|
||||
bool IsCodePreAgingActive() const {
|
||||
return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
|
||||
!is_debug();
|
||||
@ -643,8 +638,9 @@ class Compiler : public AllStatic {
|
||||
int source_length);
|
||||
|
||||
// Create a shared function info object (the code may be lazily compiled).
|
||||
static Handle<SharedFunctionInfo> GetSharedFunctionInfo(
|
||||
FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer);
|
||||
static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
|
||||
Handle<Script> script,
|
||||
CompilationInfo* outer);
|
||||
|
||||
enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
|
||||
|
||||
|
@ -1095,8 +1095,8 @@ void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
Variable* variable = decl->proxy()->var();
|
||||
switch (variable->location()) {
|
||||
case Variable::UNALLOCATED: {
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
decl->fun(), info()->script(), info());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::BuildFunctionInfo(decl->fun(), info()->script(), info());
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals()->push_back(variable->name());
|
||||
@ -1519,10 +1519,14 @@ void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
|
||||
void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
Node* context = current_context();
|
||||
|
||||
// Find or build a shared function info.
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
|
||||
CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow?
|
||||
// Build a new shared function info if we cannot find one in the baseline
|
||||
// code. We also have a stack overflow if the recursive compilation did.
|
||||
expr->InitializeSharedInfo(handle(info()->shared_info()->code()));
|
||||
Handle<SharedFunctionInfo> shared_info = expr->shared_info();
|
||||
if (shared_info.is_null()) {
|
||||
shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info());
|
||||
CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow?
|
||||
}
|
||||
|
||||
// Create node to instantiate a new closure.
|
||||
PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED;
|
||||
|
@ -2081,7 +2081,7 @@ Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
|
||||
// If the candidate is not compiled, compile it to reveal any inner
|
||||
// functions which might contain the requested source position. This
|
||||
// will compile all inner functions that cannot be compiled without a
|
||||
// context, because Compiler::GetSharedFunctionInfo checks whether the
|
||||
// context, because Compiler::BuildFunctionInfo checks whether the
|
||||
// debugger is active.
|
||||
MaybeHandle<Code> maybe_result = target_function.is_null()
|
||||
? Compiler::GetUnoptimizedCode(target)
|
||||
|
@ -844,7 +844,6 @@ Handle<Script> Factory::NewScript(Handle<String> source) {
|
||||
script->set_line_ends(heap->undefined_value());
|
||||
script->set_eval_from_shared(heap->undefined_value());
|
||||
script->set_eval_from_instructions_offset(Smi::FromInt(0));
|
||||
script->set_shared_function_infos(Smi::FromInt(0));
|
||||
script->set_flags(Smi::FromInt(0));
|
||||
|
||||
return script;
|
||||
|
@ -1388,7 +1388,7 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
|
||||
// Build the function boilerplate and instantiate it.
|
||||
Handle<SharedFunctionInfo> function_info =
|
||||
Compiler::GetSharedFunctionInfo(expr, script(), info_);
|
||||
Compiler::BuildFunctionInfo(expr, script(), info_);
|
||||
if (function_info.is_null()) {
|
||||
SetStackOverflow();
|
||||
return;
|
||||
|
@ -5291,8 +5291,11 @@ void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
DCHECK(!HasStackOverflow());
|
||||
DCHECK(current_block() != NULL);
|
||||
DCHECK(current_block()->HasPredecessor());
|
||||
Handle<SharedFunctionInfo> shared_info = Compiler::GetSharedFunctionInfo(
|
||||
expr, current_info()->script(), top_info());
|
||||
Handle<SharedFunctionInfo> shared_info = expr->shared_info();
|
||||
if (shared_info.is_null()) {
|
||||
shared_info =
|
||||
Compiler::BuildFunctionInfo(expr, current_info()->script(), top_info());
|
||||
}
|
||||
// We also have a stack overflow if the recursive compilation did.
|
||||
if (HasStackOverflow()) return;
|
||||
HFunctionLiteral* instr =
|
||||
@ -11666,7 +11669,7 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration(
|
||||
switch (variable->location()) {
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_.Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo(
|
||||
declaration->fun(), current_info()->script(), top_info());
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
|
@ -879,7 +879,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -1220,7 +1220,7 @@ void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
|
||||
CHECK(script_handle->IsScript() || script_handle->IsUndefined());
|
||||
SharedFunctionInfo::SetScript(shared_info, script_handle);
|
||||
shared_info->set_script(*script_handle);
|
||||
shared_info->DisableOptimization(kLiveEdit);
|
||||
|
||||
function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info);
|
||||
|
@ -934,7 +934,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -930,7 +930,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -5138,7 +5138,6 @@ ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
|
||||
ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
|
||||
ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
|
||||
kEvalFrominstructionsOffsetOffset)
|
||||
ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
|
||||
ACCESSORS_TO_SMI(Script, flags, kFlagsOffset)
|
||||
ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
|
||||
ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
|
||||
|
@ -983,7 +983,6 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT
|
||||
os << "\n - eval from shared: " << Brief(eval_from_shared());
|
||||
os << "\n - eval from instructions offset: "
|
||||
<< Brief(eval_from_instructions_offset());
|
||||
os << "\n - shared function infos: " << Brief(shared_function_infos());
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
|
@ -10404,55 +10404,6 @@ Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
FunctionLiteral* fun) {
|
||||
if (shared_function_infos()->IsWeakFixedArray()) {
|
||||
WeakFixedArray* array = WeakFixedArray::cast(shared_function_infos());
|
||||
for (int i = 0; i < array->Length(); i++) {
|
||||
Object* obj = array->Get(i);
|
||||
if (!obj->IsSharedFunctionInfo()) continue;
|
||||
SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
|
||||
if (fun->function_token_position() == shared->function_token_position() &&
|
||||
fun->start_position() == shared->start_position()) {
|
||||
return Handle<SharedFunctionInfo>(shared);
|
||||
}
|
||||
}
|
||||
}
|
||||
return MaybeHandle<SharedFunctionInfo>();
|
||||
}
|
||||
|
||||
|
||||
void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
|
||||
Handle<Object> script_object) {
|
||||
if (shared->script() == *script_object) return;
|
||||
// Remove shared function info from old script's list.
|
||||
if (shared->script()->IsScript()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
// Add shared function info to new script's list.
|
||||
if (script_object->IsScript()) {
|
||||
Handle<Script> script = Handle<Script>::cast(script_object);
|
||||
Handle<Object> list(script->shared_function_infos(), shared->GetIsolate());
|
||||
#ifdef DEBUG
|
||||
bool found = false;
|
||||
list = WeakFixedArray::Add(list, shared, WeakFixedArray::kAddIfNotFound,
|
||||
&found);
|
||||
CHECK(!found);
|
||||
#else
|
||||
list = WeakFixedArray::Add(list, shared, WeakFixedArray::kAlwaysAdd);
|
||||
#endif // DEBUG
|
||||
script->set_shared_function_infos(*list);
|
||||
}
|
||||
// Finally set new script.
|
||||
shared->set_script(*script_object);
|
||||
}
|
||||
|
||||
|
||||
String* SharedFunctionInfo::DebugName() {
|
||||
Object* n = name();
|
||||
if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
|
||||
|
@ -875,23 +875,16 @@ class AccessorPair;
|
||||
class AllocationSite;
|
||||
class AllocationSiteCreationContext;
|
||||
class AllocationSiteUsageContext;
|
||||
class Cell;
|
||||
class ConsString;
|
||||
class DictionaryElementsAccessor;
|
||||
class ElementsAccessor;
|
||||
class FixedArrayBase;
|
||||
class FunctionLiteral;
|
||||
class GlobalObject;
|
||||
class JSBuiltinsObject;
|
||||
class LayoutDescriptor;
|
||||
class LookupIterator;
|
||||
class ObjectHashTable;
|
||||
class ObjectVisitor;
|
||||
class PropertyCell;
|
||||
class SafepointEntry;
|
||||
class SharedFunctionInfo;
|
||||
class StringStream;
|
||||
class TypeFeedbackInfo;
|
||||
class TypeFeedbackVector;
|
||||
class WeakCell;
|
||||
|
||||
@ -1740,6 +1733,9 @@ class JSReceiver: public HeapObject {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
|
||||
};
|
||||
|
||||
// Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
|
||||
class ObjectHashTable;
|
||||
|
||||
|
||||
// The JSObject describes real heap allocated JavaScript objects with
|
||||
// properties.
|
||||
@ -4850,6 +4846,12 @@ class HandlerTable : public FixedArray {
|
||||
};
|
||||
|
||||
|
||||
// Forward declaration.
|
||||
class Cell;
|
||||
class PropertyCell;
|
||||
class SafepointEntry;
|
||||
class TypeFeedbackInfo;
|
||||
|
||||
// Code describes objects with on-the-fly generated machine code.
|
||||
class Code: public HeapObject {
|
||||
public:
|
||||
@ -6413,10 +6415,6 @@ class Script: public Struct {
|
||||
// function from which eval was called where eval was called.
|
||||
DECL_ACCESSORS(eval_from_instructions_offset, Smi)
|
||||
|
||||
// [shared_function_infos]: weak fixed array containing all shared
|
||||
// function infos created from this script.
|
||||
DECL_ACCESSORS(shared_function_infos, Object)
|
||||
|
||||
// [flags]: Holds an exciting bitfield.
|
||||
DECL_ACCESSORS(flags, Smi)
|
||||
|
||||
@ -6464,10 +6462,6 @@ class Script: public Struct {
|
||||
// Get the JS object wrapping the given script; create it if none exists.
|
||||
static Handle<JSObject> GetWrapper(Handle<Script> script);
|
||||
|
||||
// Look through the list of existing shared function infos to find one
|
||||
// that matches the function literal. Return empty handle if not found.
|
||||
MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(FunctionLiteral* fun);
|
||||
|
||||
// Dispatched behavior.
|
||||
DECLARE_PRINTER(Script)
|
||||
DECLARE_VERIFIER(Script)
|
||||
@ -6484,9 +6478,8 @@ class Script: public Struct {
|
||||
static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
|
||||
static const int kEvalFrominstructionsOffsetOffset =
|
||||
kEvalFromSharedOffset + kPointerSize;
|
||||
static const int kSharedFunctionInfosOffset =
|
||||
static const int kFlagsOffset =
|
||||
kEvalFrominstructionsOffsetOffset + kPointerSize;
|
||||
static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
|
||||
static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
|
||||
static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
|
||||
static const int kSize = kSourceMappingUrlOffset + kPointerSize;
|
||||
@ -6617,11 +6610,6 @@ class SharedFunctionInfo: public HeapObject {
|
||||
Handle<FixedArray> literals,
|
||||
BailoutId osr_ast_id);
|
||||
|
||||
// Set up the link between shared function info and the script. The shared
|
||||
// function info is added to the list on the script.
|
||||
static void SetScript(Handle<SharedFunctionInfo> shared,
|
||||
Handle<Object> script_object);
|
||||
|
||||
// Layout description of the optimized code map.
|
||||
static const int kNextMapIndex = 0;
|
||||
static const int kEntriesStart = 1;
|
||||
@ -7501,6 +7489,9 @@ class JSGlobalProxy : public JSObject {
|
||||
};
|
||||
|
||||
|
||||
// Forward declaration.
|
||||
class JSBuiltinsObject;
|
||||
|
||||
// Common super class for JavaScript global objects and the special
|
||||
// builtins global objects.
|
||||
class GlobalObject: public JSObject {
|
||||
|
@ -898,7 +898,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -232,6 +232,7 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
||||
target_shared->set_feedback_vector(source_shared->feedback_vector());
|
||||
target_shared->set_internal_formal_parameter_count(
|
||||
source_shared->internal_formal_parameter_count());
|
||||
target_shared->set_script(source_shared->script());
|
||||
target_shared->set_start_position_and_type(
|
||||
source_shared->start_position_and_type());
|
||||
target_shared->set_end_position(source_shared->end_position());
|
||||
@ -241,8 +242,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
||||
source_shared->opt_count_and_bailout_reason());
|
||||
target_shared->set_native(was_native);
|
||||
target_shared->set_profiler_ticks(source_shared->profiler_ticks());
|
||||
SharedFunctionInfo::SetScript(
|
||||
target_shared, Handle<Object>(source_shared->script(), isolate));
|
||||
|
||||
// Set the code of the target function.
|
||||
target->ReplaceCode(source_shared->code());
|
||||
|
@ -1875,10 +1875,6 @@ void Serializer::ObjectSerializer::Serialize() {
|
||||
// Clear cached line ends.
|
||||
Object* undefined = serializer_->isolate()->heap()->undefined_value();
|
||||
Script::cast(object_)->set_line_ends(undefined);
|
||||
Object* shared_list = Script::cast(object_)->shared_function_infos();
|
||||
if (shared_list->IsWeakFixedArray()) {
|
||||
WeakFixedArray::cast(shared_list)->Compact();
|
||||
}
|
||||
}
|
||||
|
||||
if (object_->IsExternalString()) {
|
||||
@ -2299,7 +2295,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
|
||||
DCHECK(code_object->has_reloc_info_for_serialization());
|
||||
// Only serialize the code for the toplevel function unless specified
|
||||
// by flag. Replace code of inner functions by the lazy compile builtin.
|
||||
// This is safe, as checked in Compiler::GetSharedFunctionInfo.
|
||||
// This is safe, as checked in Compiler::BuildFunctionInfo.
|
||||
if (code_object != main_code_ && !FLAG_serialize_inner) {
|
||||
SerializeBuiltin(Builtins::kCompileLazy, how_to_code, where_to_point);
|
||||
} else {
|
||||
|
@ -346,7 +346,9 @@ void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
|
||||
}
|
||||
|
||||
|
||||
void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {}
|
||||
void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
expr->InitializeSharedInfo(Handle<Code>(info_->closure()->shared()->code()));
|
||||
}
|
||||
|
||||
|
||||
void AstTyper::VisitClassLiteral(ClassLiteral* expr) {}
|
||||
|
@ -901,7 +901,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -867,7 +867,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
case Variable::UNALLOCATED: {
|
||||
globals_->Add(variable->name(), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -5924,53 +5924,6 @@ TEST(MessageObjectLeak) {
|
||||
}
|
||||
|
||||
|
||||
static void CheckEqualSharedFunctionInfos(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Handle<Object> obj1 = v8::Utils::OpenHandle(*args[0]);
|
||||
Handle<Object> obj2 = v8::Utils::OpenHandle(*args[1]);
|
||||
Handle<JSFunction> fun1 = Handle<JSFunction>::cast(obj1);
|
||||
Handle<JSFunction> fun2 = Handle<JSFunction>::cast(obj2);
|
||||
CHECK(fun1->shared() == fun2->shared());
|
||||
}
|
||||
|
||||
|
||||
static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Handle<Object> obj = v8::Utils::OpenHandle(*args[0]);
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
|
||||
fun->ReplaceCode(*isolate->builtins()->CompileLazy());
|
||||
fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy());
|
||||
isolate->heap()->CollectAllAvailableGarbage("remove code and gc");
|
||||
}
|
||||
|
||||
|
||||
TEST(CanonicalSharedFunctionInfo) {
|
||||
CcTest::InitializeVM();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
|
||||
global->Set(isolate, "check", v8::FunctionTemplate::New(
|
||||
isolate, CheckEqualSharedFunctionInfos));
|
||||
global->Set(isolate, "remove",
|
||||
v8::FunctionTemplate::New(isolate, RemoveCodeAndGC));
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
|
||||
v8::Context::Scope cscope(context);
|
||||
CompileRun(
|
||||
"function f() { return function g() {}; }"
|
||||
"var g1 = f();"
|
||||
"remove(f);"
|
||||
"var g2 = f();"
|
||||
"check(g1, g2);");
|
||||
|
||||
CompileRun(
|
||||
"function f() { return (function() { return function g() {}; })(); }"
|
||||
"var g1 = f();"
|
||||
"remove(f);"
|
||||
"var g2 = f();"
|
||||
"check(g1, g2);");
|
||||
}
|
||||
|
||||
|
||||
TEST(OldGenerationAllocationThroughput) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
|
@ -53,6 +53,3 @@ assertTrue(%HasFastObjectElements(second_object_array));
|
||||
assertFalse(%HasFastSmiElements(second_object_array));
|
||||
assertTrue(%HaveSameMap(first_object_array, second_object_array));
|
||||
assertFalse(%HaveSameMap(first_smi_array, second_object_array));
|
||||
|
||||
%ClearFunctionTypeFeedback(Loader);
|
||||
%ClearFunctionTypeFeedback(Migrator);
|
||||
|
Loading…
Reference in New Issue
Block a user