Revert "Keep a canonical list of shared function infos."

Speculative revert in the hopes of fixing serializer crashes seen in canary.

This reverts commit c166945083, as well as
followup change "Do not look for existing shared function info when compiling a new script."
(commit 7c43967bb7).

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:
adamk 2015-06-23 15:59:19 -07:00 committed by Commit bot
parent 57306b59e8
commit 3164aa7483
29 changed files with 94 additions and 209 deletions

View File

@ -933,7 +933,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -931,7 +931,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack overflow exception. // Check for stack overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -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, ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
Kind kind, bool is_static, Kind kind, bool is_static,
bool is_computed_name) bool is_computed_name)

View File

@ -2512,6 +2512,8 @@ class FunctionLiteral final : public Expression {
bool AllowsLazyCompilation(); bool AllowsLazyCompilation();
bool AllowsLazyCompilationWithoutContext(); bool AllowsLazyCompilationWithoutContext();
void InitializeSharedInfo(Handle<Code> code);
Handle<String> debug_name() const { Handle<String> debug_name() const {
if (raw_name_ != NULL && !raw_name_->IsEmpty()) { if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
return raw_name_->string(); return raw_name_->string();
@ -2546,6 +2548,9 @@ class FunctionLiteral final : public Expression {
inferred_name_ = Handle<String>(); 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_); } bool pretenure() { return Pretenure::decode(bitfield_); }
void set_pretenure() { bitfield_ |= Pretenure::encode(true); } void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
@ -2627,6 +2632,7 @@ class FunctionLiteral final : public Expression {
private: private:
const AstRawString* raw_name_; const AstRawString* raw_name_;
Handle<String> name_; Handle<String> name_;
Handle<SharedFunctionInfo> shared_info_;
Scope* scope_; Scope* scope_;
ZoneList<Statement*>* body_; ZoneList<Statement*>* body_;
const AstString* raw_inferred_name_; const AstString* raw_inferred_name_;

View File

@ -563,10 +563,10 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Handle<String> source = factory->NewStringFromStaticChars("() {}"); Handle<String> source = factory->NewStringFromStaticChars("() {}");
Handle<Script> script = factory->NewScript(source); Handle<Script> script = factory->NewScript(source);
script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 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_start_position(0);
empty_function->shared()->set_end_position(source->length()); empty_function->shared()->set_end_position(source->length());
empty_function->shared()->DontAdaptArguments(); empty_function->shared()->DontAdaptArguments();
SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
// Set prototypes for the function maps. // Set prototypes for the function maps.
Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(), Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),

View File

@ -32,6 +32,7 @@
// ~CodeGenerator // ~CodeGenerator
// Generate // Generate
// ComputeLazyCompile // ComputeLazyCompile
// BuildFunctionInfo
// ProcessDeclarations // ProcessDeclarations
// DeclareGlobals // DeclareGlobals
// CheckForInlineRuntimeCall // CheckForInlineRuntimeCall

View File

@ -1015,9 +1015,6 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
PostponeInterruptsScope postpone(info.isolate()); PostponeInterruptsScope postpone(info.isolate());
VMState<COMPILER> state(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(); info.parse_info()->set_global();
if (!Parser::ParseStatic(info.parse_info())) return; if (!Parser::ParseStatic(info.parse_info())) return;
@ -1078,8 +1075,6 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
} }
} }
info->MarkAsNewScript();
FunctionLiteral* lit = info->function(); FunctionLiteral* lit = info->function();
LiveEditFunctionTracker live_edit_tracker(isolate, lit); LiveEditFunctionTracker live_edit_tracker(isolate, lit);
@ -1106,7 +1101,7 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
SharedFunctionInfo::InitFromFunctionLiteral(result, lit); SharedFunctionInfo::InitFromFunctionLiteral(result, lit);
SharedFunctionInfo::SetScript(result, script); result->set_script(*script);
result->set_is_toplevel(true); result->set_is_toplevel(true);
Handle<String> script_name = script->name()->IsString() 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, FunctionLiteral* literal, Handle<Script> script,
CompilationInfo* outer_info) { CompilationInfo* outer_info) {
// Precondition: code has been parsed and scopes have been analyzed. // 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; Zone zone;
ParseInfo parse_info(&zone, script); ParseInfo parse_info(&zone, script);
CompilationInfo info(&parse_info); CompilationInfo info(&parse_info);
@ -1362,7 +1342,6 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
parse_info.set_scope(literal->scope()); parse_info.set_scope(literal->scope());
parse_info.set_language_mode(literal->scope()->language_mode()); parse_info.set_language_mode(literal->scope()->language_mode());
if (outer_info->will_serialize()) info.PrepareForSerializing(); if (outer_info->will_serialize()) info.PrepareForSerializing();
if (outer_info->is_new_script()) info.MarkAsNewScript();
Isolate* isolate = info.isolate(); Isolate* isolate = info.isolate();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
@ -1416,34 +1395,25 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
return Handle<SharedFunctionInfo>::null(); return Handle<SharedFunctionInfo>::null();
} }
if (maybe_existing.is_null()) { // Create a shared function info object.
// Create a shared function info object. Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo(
Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( literal->name(), literal->materialized_literal_count(), literal->kind(),
literal->name(), literal->materialized_literal_count(), literal->kind(), info.code(), scope_info, info.feedback_vector());
info.code(), scope_info, info.feedback_vector());
SharedFunctionInfo::InitFromFunctionLiteral(result, literal); SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
SharedFunctionInfo::SetScript(result, script); result->set_script(*script);
result->set_is_toplevel(false); result->set_is_toplevel(false);
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); result->set_allows_lazy_compilation(literal->AllowsLazyCompilation());
result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
// Set the expected number of properties for instances and return // Set the expected number of properties for instances and return
// the resulting function. // the resulting function.
SetExpectedNofPropertiesFromEstimate(result, SetExpectedNofPropertiesFromEstimate(result,
literal->expected_property_count()); literal->expected_property_count());
live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
return result; 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;
}
} }

View File

@ -127,8 +127,7 @@ class CompilationInfo {
kSplittingEnabled = 1 << 13, kSplittingEnabled = 1 << 13,
kTypeFeedbackEnabled = 1 << 14, kTypeFeedbackEnabled = 1 << 14,
kDeoptimizationEnabled = 1 << 15, kDeoptimizationEnabled = 1 << 15,
kSourcePositionsEnabled = 1 << 16, kSourcePositionsEnabled = 1 << 16
kNewScript = 1 << 17,
}; };
explicit CompilationInfo(ParseInfo* parse_info); explicit CompilationInfo(ParseInfo* parse_info);
@ -246,10 +245,6 @@ class CompilationInfo {
bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
void MarkAsNewScript() { SetFlag(kNewScript); }
bool is_new_script() const { return GetFlag(kNewScript); }
bool IsCodePreAgingActive() const { bool IsCodePreAgingActive() const {
return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
!is_debug(); !is_debug();
@ -643,8 +638,9 @@ class Compiler : public AllStatic {
int source_length); int source_length);
// Create a shared function info object (the code may be lazily compiled). // Create a shared function info object (the code may be lazily compiled).
static Handle<SharedFunctionInfo> GetSharedFunctionInfo( static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer); Handle<Script> script,
CompilationInfo* outer);
enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };

View File

@ -1095,8 +1095,8 @@ void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
Variable* variable = decl->proxy()->var(); Variable* variable = decl->proxy()->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( Handle<SharedFunctionInfo> function =
decl->fun(), info()->script(), info()); Compiler::BuildFunctionInfo(decl->fun(), info()->script(), info());
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals()->push_back(variable->name()); globals()->push_back(variable->name());
@ -1519,10 +1519,14 @@ void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
Node* context = current_context(); Node* context = current_context();
// Find or build a shared function info. // Build a new shared function info if we cannot find one in the baseline
Handle<SharedFunctionInfo> shared_info = // code. We also have a stack overflow if the recursive compilation did.
Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); expr->InitializeSharedInfo(handle(info()->shared_info()->code()));
CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? 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. // Create node to instantiate a new closure.
PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED;

View File

@ -2081,7 +2081,7 @@ Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
// If the candidate is not compiled, compile it to reveal any inner // If the candidate is not compiled, compile it to reveal any inner
// functions which might contain the requested source position. This // functions which might contain the requested source position. This
// will compile all inner functions that cannot be compiled without a // 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. // debugger is active.
MaybeHandle<Code> maybe_result = target_function.is_null() MaybeHandle<Code> maybe_result = target_function.is_null()
? Compiler::GetUnoptimizedCode(target) ? Compiler::GetUnoptimizedCode(target)

View File

@ -844,7 +844,6 @@ Handle<Script> Factory::NewScript(Handle<String> source) {
script->set_line_ends(heap->undefined_value()); script->set_line_ends(heap->undefined_value());
script->set_eval_from_shared(heap->undefined_value()); script->set_eval_from_shared(heap->undefined_value());
script->set_eval_from_instructions_offset(Smi::FromInt(0)); script->set_eval_from_instructions_offset(Smi::FromInt(0));
script->set_shared_function_infos(Smi::FromInt(0));
script->set_flags(Smi::FromInt(0)); script->set_flags(Smi::FromInt(0));
return script; return script;

View File

@ -1388,7 +1388,7 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
// Build the function boilerplate and instantiate it. // Build the function boilerplate and instantiate it.
Handle<SharedFunctionInfo> function_info = Handle<SharedFunctionInfo> function_info =
Compiler::GetSharedFunctionInfo(expr, script(), info_); Compiler::BuildFunctionInfo(expr, script(), info_);
if (function_info.is_null()) { if (function_info.is_null()) {
SetStackOverflow(); SetStackOverflow();
return; return;

View File

@ -5291,8 +5291,11 @@ void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
DCHECK(!HasStackOverflow()); DCHECK(!HasStackOverflow());
DCHECK(current_block() != NULL); DCHECK(current_block() != NULL);
DCHECK(current_block()->HasPredecessor()); DCHECK(current_block()->HasPredecessor());
Handle<SharedFunctionInfo> shared_info = Compiler::GetSharedFunctionInfo( Handle<SharedFunctionInfo> shared_info = expr->shared_info();
expr, current_info()->script(), top_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. // We also have a stack overflow if the recursive compilation did.
if (HasStackOverflow()) return; if (HasStackOverflow()) return;
HFunctionLiteral* instr = HFunctionLiteral* instr =
@ -11666,7 +11669,7 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration(
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_.Add(variable->name(), zone()); globals_.Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo(
declaration->fun(), current_info()->script(), top_info()); declaration->fun(), current_info()->script(), top_info());
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();

View File

@ -879,7 +879,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -1220,7 +1220,7 @@ void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo> shared_info =
UnwrapSharedFunctionInfoFromJSValue(function_wrapper); UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
CHECK(script_handle->IsScript() || script_handle->IsUndefined()); CHECK(script_handle->IsScript() || script_handle->IsUndefined());
SharedFunctionInfo::SetScript(shared_info, script_handle); shared_info->set_script(*script_handle);
shared_info->DisableOptimization(kLiveEdit); shared_info->DisableOptimization(kLiveEdit);
function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info); function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info);

View File

@ -934,7 +934,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -930,7 +930,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -5138,7 +5138,6 @@ ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset) ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ACCESSORS_TO_SMI(Script, eval_from_instructions_offset, ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
kEvalFrominstructionsOffsetOffset) kEvalFrominstructionsOffsetOffset)
ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
ACCESSORS_TO_SMI(Script, flags, kFlagsOffset) ACCESSORS_TO_SMI(Script, flags, kFlagsOffset)
ACCESSORS(Script, source_url, Object, kSourceUrlOffset) ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset) ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)

View File

@ -983,7 +983,6 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT
os << "\n - eval from shared: " << Brief(eval_from_shared()); os << "\n - eval from shared: " << Brief(eval_from_shared());
os << "\n - eval from instructions offset: " os << "\n - eval from instructions offset: "
<< Brief(eval_from_instructions_offset()); << Brief(eval_from_instructions_offset());
os << "\n - shared function infos: " << Brief(shared_function_infos());
os << "\n"; os << "\n";
} }

View File

@ -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() { String* SharedFunctionInfo::DebugName() {
Object* n = name(); Object* n = name();
if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();

View File

@ -875,23 +875,16 @@ class AccessorPair;
class AllocationSite; class AllocationSite;
class AllocationSiteCreationContext; class AllocationSiteCreationContext;
class AllocationSiteUsageContext; class AllocationSiteUsageContext;
class Cell;
class ConsString; class ConsString;
class DictionaryElementsAccessor; class DictionaryElementsAccessor;
class ElementsAccessor; class ElementsAccessor;
class FixedArrayBase; class FixedArrayBase;
class FunctionLiteral; class FunctionLiteral;
class GlobalObject; class GlobalObject;
class JSBuiltinsObject;
class LayoutDescriptor; class LayoutDescriptor;
class LookupIterator; class LookupIterator;
class ObjectHashTable;
class ObjectVisitor; class ObjectVisitor;
class PropertyCell;
class SafepointEntry;
class SharedFunctionInfo;
class StringStream; class StringStream;
class TypeFeedbackInfo;
class TypeFeedbackVector; class TypeFeedbackVector;
class WeakCell; class WeakCell;
@ -1740,6 +1733,9 @@ class JSReceiver: public HeapObject {
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver); DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
}; };
// Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
class ObjectHashTable;
// The JSObject describes real heap allocated JavaScript objects with // The JSObject describes real heap allocated JavaScript objects with
// properties. // 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. // Code describes objects with on-the-fly generated machine code.
class Code: public HeapObject { class Code: public HeapObject {
public: public:
@ -6413,10 +6415,6 @@ class Script: public Struct {
// function from which eval was called where eval was called. // function from which eval was called where eval was called.
DECL_ACCESSORS(eval_from_instructions_offset, Smi) 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. // [flags]: Holds an exciting bitfield.
DECL_ACCESSORS(flags, Smi) 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. // Get the JS object wrapping the given script; create it if none exists.
static Handle<JSObject> GetWrapper(Handle<Script> script); 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. // Dispatched behavior.
DECLARE_PRINTER(Script) DECLARE_PRINTER(Script)
DECLARE_VERIFIER(Script) DECLARE_VERIFIER(Script)
@ -6484,9 +6478,8 @@ class Script: public Struct {
static const int kEvalFromSharedOffset = kIdOffset + kPointerSize; static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
static const int kEvalFrominstructionsOffsetOffset = static const int kEvalFrominstructionsOffsetOffset =
kEvalFromSharedOffset + kPointerSize; kEvalFromSharedOffset + kPointerSize;
static const int kSharedFunctionInfosOffset = static const int kFlagsOffset =
kEvalFrominstructionsOffsetOffset + kPointerSize; kEvalFrominstructionsOffsetOffset + kPointerSize;
static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
static const int kSourceUrlOffset = kFlagsOffset + kPointerSize; static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize; static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
static const int kSize = kSourceMappingUrlOffset + kPointerSize; static const int kSize = kSourceMappingUrlOffset + kPointerSize;
@ -6617,11 +6610,6 @@ class SharedFunctionInfo: public HeapObject {
Handle<FixedArray> literals, Handle<FixedArray> literals,
BailoutId osr_ast_id); 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. // Layout description of the optimized code map.
static const int kNextMapIndex = 0; static const int kNextMapIndex = 0;
static const int kEntriesStart = 1; 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 // Common super class for JavaScript global objects and the special
// builtins global objects. // builtins global objects.
class GlobalObject: public JSObject { class GlobalObject: public JSObject {

View File

@ -898,7 +898,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -232,6 +232,7 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
target_shared->set_feedback_vector(source_shared->feedback_vector()); target_shared->set_feedback_vector(source_shared->feedback_vector());
target_shared->set_internal_formal_parameter_count( target_shared->set_internal_formal_parameter_count(
source_shared->internal_formal_parameter_count()); source_shared->internal_formal_parameter_count());
target_shared->set_script(source_shared->script());
target_shared->set_start_position_and_type( target_shared->set_start_position_and_type(
source_shared->start_position_and_type()); source_shared->start_position_and_type());
target_shared->set_end_position(source_shared->end_position()); target_shared->set_end_position(source_shared->end_position());
@ -241,8 +242,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
source_shared->opt_count_and_bailout_reason()); source_shared->opt_count_and_bailout_reason());
target_shared->set_native(was_native); target_shared->set_native(was_native);
target_shared->set_profiler_ticks(source_shared->profiler_ticks()); 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. // Set the code of the target function.
target->ReplaceCode(source_shared->code()); target->ReplaceCode(source_shared->code());

View File

@ -1875,10 +1875,6 @@ void Serializer::ObjectSerializer::Serialize() {
// Clear cached line ends. // Clear cached line ends.
Object* undefined = serializer_->isolate()->heap()->undefined_value(); Object* undefined = serializer_->isolate()->heap()->undefined_value();
Script::cast(object_)->set_line_ends(undefined); 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()) { if (object_->IsExternalString()) {
@ -2299,7 +2295,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
DCHECK(code_object->has_reloc_info_for_serialization()); DCHECK(code_object->has_reloc_info_for_serialization());
// Only serialize the code for the toplevel function unless specified // Only serialize the code for the toplevel function unless specified
// by flag. Replace code of inner functions by the lazy compile builtin. // 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) { if (code_object != main_code_ && !FLAG_serialize_inner) {
SerializeBuiltin(Builtins::kCompileLazy, how_to_code, where_to_point); SerializeBuiltin(Builtins::kCompileLazy, how_to_code, where_to_point);
} else { } else {

View File

@ -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) {} void AstTyper::VisitClassLiteral(ClassLiteral* expr) {}

View File

@ -901,7 +901,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -867,7 +867,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone()); globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow(); if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone()); globals_->Add(function, zone());

View File

@ -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) { TEST(OldGenerationAllocationThroughput) {
CcTest::InitializeVM(); CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());

View File

@ -53,6 +53,3 @@ assertTrue(%HasFastObjectElements(second_object_array));
assertFalse(%HasFastSmiElements(second_object_array)); assertFalse(%HasFastSmiElements(second_object_array));
assertTrue(%HaveSameMap(first_object_array, second_object_array)); assertTrue(%HaveSameMap(first_object_array, second_object_array));
assertFalse(%HaveSameMap(first_smi_array, second_object_array)); assertFalse(%HaveSameMap(first_smi_array, second_object_array));
%ClearFunctionTypeFeedback(Loader);
%ClearFunctionTypeFeedback(Migrator);