Version 4.5.74.1 (cherry-pick)

Merged 3164aa7483cb476da84895a3c9810015758fccf9

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

BUG=chromium:503552,v8:4132
LOG=N
TBR=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1202413004.

Cr-Commit-Position: refs/heads/4.5.74@{#2}
Cr-Branched-From: df472240285a93f25edac20100db2240fae5c7c6-refs/heads/master@{#29237}
diff --git a/include/v8-version.h b/include/v8-version.h
index c59b3f9..a85d9fb 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 4
 #define V8_MINOR_VERSION 5
 #define V8_BUILD_NUMBER 74
-#define V8_PATCH_LEVEL 0
+#define V8_PATCH_LEVEL 1
 
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index b816f1e..cba69e9 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -931,7 +931,7 @@
     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());
diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc
index ea25822..05c2c6a 100644
--- a/src/arm64/full-codegen-arm64.cc
+++ b/src/arm64/full-codegen-arm64.cc
@@ -923,7 +923,7 @@
     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());
diff --git a/src/ast.cc b/src/ast.cc
index 00d0100..bd0c516 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -241,6 +241,25 @@
 }
 
 
+// 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)
diff --git a/src/ast.h b/src/ast.h
index 3a3d896..61a6ea9 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -2512,6 +2512,8 @@
   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 @@
     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 @@
  private:
   const AstRawString* raw_name_;
   Handle<String> name_;
+  Handle<SharedFunctionInfo> shared_info_;
   Scope* scope_;
   ZoneList<Statement*>* body_;
   const AstString* raw_inferred_name_;
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index b0a6257..f59830e 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -563,10 +563,10 @@
   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(),
diff --git a/src/codegen.h b/src/codegen.h
index cce33e4..0e0cf1d 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -32,6 +32,7 @@
 //   ~CodeGenerator
 //   Generate
 //   ComputeLazyCompile
+//   BuildFunctionInfo
 //   ProcessDeclarations
 //   DeclareGlobals
 //   CheckForInlineRuntimeCall
diff --git a/src/compiler.cc b/src/compiler.cc
index 0beb904..fc27d76 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1015,9 +1015,6 @@
   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 @@
       }
     }
 
-    info->MarkAsNewScript();
-
     FunctionLiteral* lit = info->function();
     LiveEditFunctionTracker live_edit_tracker(isolate, lit);
 
@@ -1106,7 +1101,7 @@
 
     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::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 @@
   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 @@
     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;
 }
 
 
diff --git a/src/compiler.h b/src/compiler.h
index cbcfec6..c90bf91 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -127,8 +127,7 @@
     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 @@
 
   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 @@
                                                           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 };
 
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 4de9a64..1147f85 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -1095,8 +1095,8 @@
   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::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;
diff --git a/src/debug.cc b/src/debug.cc
index 3987d9d3..d966b6e 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -2081,7 +2081,7 @@
       // 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)
diff --git a/src/factory.cc b/src/factory.cc
index 387c5d1..ba93e6c 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -844,7 +844,6 @@
   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;
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index d6b4d6b..3bd924f 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -1388,7 +1388,7 @@
 
   // 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;
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 0019b6d..48043e6 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5291,8 +5291,11 @@
   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 @@
   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();
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 9c09e31..449904a 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -870,7 +870,7 @@
     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());
diff --git a/src/liveedit.cc b/src/liveedit.cc
index afa0e13..982ac10 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -1220,7 +1220,7 @@
   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);
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 5e3fe80..794a472 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -923,7 +923,7 @@
     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());
diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc
index 9a34b41..da8314c 100644
--- a/src/mips64/full-codegen-mips64.cc
+++ b/src/mips64/full-codegen-mips64.cc
@@ -920,7 +920,7 @@
     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());
diff --git a/src/objects-inl.h b/src/objects-inl.h
index c6c3117..c508dd2 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -5138,7 +5138,6 @@
 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)
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 8c7e991..6663639 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -983,7 +983,6 @@
   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";
 }
 
diff --git a/src/objects.cc b/src/objects.cc
index 262803f..fd66419 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -10404,55 +10404,6 @@
 }
 
 
-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();
diff --git a/src/objects.h b/src/objects.h
index d6f0608..785fa98 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -875,23 +875,16 @@
 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 @@
   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 @@
 };
 
 
+// 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 @@
   // 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 @@
   // 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 @@
   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 @@
                                     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 @@
 };
 
 
+// Forward declaration.
+class JSBuiltinsObject;
+
 // Common super class for JavaScript global objects and the special
 // builtins global objects.
 class GlobalObject: public JSObject {
diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc
index ad0b1b6..ddb71b5 100644
--- a/src/ppc/full-codegen-ppc.cc
+++ b/src/ppc/full-codegen-ppc.cc
@@ -898,7 +898,7 @@
     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());
diff --git a/src/runtime/runtime-function.cc b/src/runtime/runtime-function.cc
index e7a027d..6283f1e 100644
--- a/src/runtime/runtime-function.cc
+++ b/src/runtime/runtime-function.cc
@@ -232,6 +232,7 @@
   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 @@
       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());
diff --git a/src/snapshot/serialize.cc b/src/snapshot/serialize.cc
index a8d0f51..7410c3b 100644
--- a/src/snapshot/serialize.cc
+++ b/src/snapshot/serialize.cc
@@ -1875,10 +1875,6 @@
     // 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 @@
         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 {
diff --git a/src/typing.cc b/src/typing.cc
index 6f5cd1c..0d8ed52 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -346,7 +346,9 @@
 }
 
 
-void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {}
+void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
+  expr->InitializeSharedInfo(Handle<Code>(info_->closure()->shared()->code()));
+}
 
 
 void AstTyper::VisitClassLiteral(ClassLiteral* expr) {}
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 859efec..ff7bfe8 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -892,7 +892,7 @@
     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());
diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc
index 450953a..683eae9 100644
--- a/src/x87/full-codegen-x87.cc
+++ b/src/x87/full-codegen-x87.cc
@@ -867,7 +867,7 @@
     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());
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 668fb01..e0c2818 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -5924,53 +5924,6 @@
 }
 
 
-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());
diff --git a/test/mjsunit/regress/regress-4121.js b/test/mjsunit/regress/regress-4121.js
index bef0b47..3d777c2 100644
--- a/test/mjsunit/regress/regress-4121.js
+++ b/test/mjsunit/regress/regress-4121.js
@@ -53,6 +53,3 @@
 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);