diff --git a/src/compiler.h b/src/compiler.h
index 44df9e0..f950ef7 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -1,63 +1,107 @@
 // Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #ifndef V8_COMPILER_H_
 #define V8_COMPILER_H_
 
-#include "allocation.h"
-#include "ast.h"
-#include "zone.h"
+#include "src/allocation.h"
+#include "src/ast.h"
+#include "src/bailout-reason.h"
+#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 
-class ScriptDataImpl;
+class AstValueFactory;
+class HydrogenCodeStub;
+
+// ParseRestriction is used to restrict the set of valid statements in a
+// unit of compilation.  Restriction violations cause a syntax error.
+enum ParseRestriction {
+  NO_PARSE_RESTRICTION,         // All expressions are allowed.
+  ONLY_SINGLE_FUNCTION_LITERAL  // Only a single FunctionLiteral expression.
+};
+
+struct OffsetRange {
+  OffsetRange(int from, int to) : from(from), to(to) {}
+  int from;
+  int to;
+};
+
+
+class ScriptData {
+ public:
+  ScriptData(const byte* data, int length);
+  ~ScriptData() {
+    if (owns_data_) DeleteArray(data_);
+  }
+
+  const byte* data() const { return data_; }
+  int length() const { return length_; }
+
+  void AcquireDataOwnership() {
+    DCHECK(!owns_data_);
+    owns_data_ = true;
+  }
+
+  void ReleaseDataOwnership() {
+    DCHECK(owns_data_);
+    owns_data_ = false;
+  }
+
+ private:
+  bool owns_data_;
+  const byte* data_;
+  int length_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScriptData);
+};
 
 // CompilationInfo encapsulates some information known at compile time.  It
 // is constructed based on the resources available at compile-time.
-class CompilationInfo BASE_EMBEDDED {
+class CompilationInfo {
  public:
-  explicit CompilationInfo(Handle<Script> script);
-  explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info);
-  explicit CompilationInfo(Handle<JSFunction> closure);
+  // Various configuration flags for a compilation, as well as some properties
+  // of the compiled code produced by a compilation.
+  enum Flag {
+    kLazy = 1 << 0,
+    kEval = 1 << 1,
+    kGlobal = 1 << 2,
+    kStrictMode = 1 << 3,
+    kThisHasUses = 1 << 4,
+    kNative = 1 << 5,
+    kDeferredCalling = 1 << 6,
+    kNonDeferredCalling = 1 << 7,
+    kSavesCallerDoubles = 1 << 8,
+    kRequiresFrame = 1 << 9,
+    kMustNotHaveEagerFrame = 1 << 10,
+    kDeoptimizationSupport = 1 << 11,
+    kDebug = 1 << 12,
+    kCompilingForDebugging = 1 << 13,
+    kParseRestriction = 1 << 14,
+    kSerializing = 1 << 15,
+    kContextSpecializing = 1 << 16,
+    kInliningEnabled = 1 << 17,
+    kTypingEnabled = 1 << 18,
+    kDisableFutureOptimization = 1 << 19
+  };
 
-  Isolate* isolate() {
-    ASSERT(Isolate::Current() == isolate_);
+  CompilationInfo(Handle<JSFunction> closure, Zone* zone);
+  CompilationInfo(Isolate* isolate, Zone* zone);
+  virtual ~CompilationInfo();
+
+  Isolate* isolate() const {
     return isolate_;
   }
-  bool is_lazy() const { return IsLazy::decode(flags_); }
-  bool is_eval() const { return IsEval::decode(flags_); }
-  bool is_global() const { return IsGlobal::decode(flags_); }
-  bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
-  bool is_extended_mode() const { return language_mode() == EXTENDED_MODE; }
-  LanguageMode language_mode() const {
-    return LanguageModeField::decode(flags_);
+  Zone* zone() { return zone_; }
+  bool is_osr() const { return !osr_ast_id_.IsNone(); }
+  bool is_lazy() const { return GetFlag(kLazy); }
+  bool is_eval() const { return GetFlag(kEval); }
+  bool is_global() const { return GetFlag(kGlobal); }
+  StrictMode strict_mode() const {
+    return GetFlag(kStrictMode) ? STRICT : SLOPPY;
   }
-  bool is_in_loop() const { return IsInLoop::decode(flags_); }
   FunctionLiteral* function() const { return function_; }
   Scope* scope() const { return scope_; }
   Scope* global_scope() const { return global_scope_; }
@@ -65,110 +109,297 @@
   Handle<JSFunction> closure() const { return closure_; }
   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
   Handle<Script> script() const { return script_; }
+  void set_script(Handle<Script> script) { script_ = script; }
+  HydrogenCodeStub* code_stub() const {return code_stub_; }
   v8::Extension* extension() const { return extension_; }
-  ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
-  Handle<Context> calling_context() const { return calling_context_; }
-  int osr_ast_id() const { return osr_ast_id_; }
+  ScriptData** cached_data() const { return cached_data_; }
+  ScriptCompiler::CompileOptions compile_options() const {
+    return compile_options_;
+  }
+  ScriptCompiler::ExternalSourceStream* source_stream() const {
+    return source_stream_;
+  }
+  ScriptCompiler::StreamedSource::Encoding source_stream_encoding() const {
+    return source_stream_encoding_;
+  }
+  Handle<Context> context() const { return context_; }
+  BailoutId osr_ast_id() const { return osr_ast_id_; }
+  Handle<Code> unoptimized_code() const { return unoptimized_code_; }
+  int opt_count() const { return opt_count_; }
+  int num_parameters() const;
+  int num_heap_slots() const;
+  Code::Flags flags() const;
 
   void MarkAsEval() {
-    ASSERT(!is_lazy());
-    flags_ |= IsEval::encode(true);
+    DCHECK(!is_lazy());
+    SetFlag(kEval);
   }
+
   void MarkAsGlobal() {
-    ASSERT(!is_lazy());
-    flags_ |= IsGlobal::encode(true);
+    DCHECK(!is_lazy());
+    SetFlag(kGlobal);
   }
-  void SetLanguageMode(LanguageMode language_mode) {
-    ASSERT(this->language_mode() == CLASSIC_MODE ||
-           this->language_mode() == language_mode ||
-           language_mode == EXTENDED_MODE);
-    flags_ = LanguageModeField::update(flags_, language_mode);
+
+  void set_parameter_count(int parameter_count) {
+    DCHECK(IsStub());
+    parameter_count_ = parameter_count;
   }
-  void MarkAsInLoop() {
-    ASSERT(is_lazy());
-    flags_ |= IsInLoop::encode(true);
+
+  void set_this_has_uses(bool has_no_uses) {
+    SetFlag(kThisHasUses, has_no_uses);
   }
-  void MarkAsNative() {
-    flags_ |= IsNative::encode(true);
+
+  bool this_has_uses() { return GetFlag(kThisHasUses); }
+
+  void SetStrictMode(StrictMode strict_mode) {
+    SetFlag(kStrictMode, strict_mode == STRICT);
   }
-  bool is_native() const {
-    return IsNative::decode(flags_);
+
+  void MarkAsNative() { SetFlag(kNative); }
+
+  bool is_native() const { return GetFlag(kNative); }
+
+  bool is_calling() const {
+    return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling);
   }
+
+  void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); }
+
+  bool is_deferred_calling() const { return GetFlag(kDeferredCalling); }
+
+  void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); }
+
+  bool is_non_deferred_calling() const { return GetFlag(kNonDeferredCalling); }
+
+  void MarkAsSavesCallerDoubles() { SetFlag(kSavesCallerDoubles); }
+
+  bool saves_caller_doubles() const { return GetFlag(kSavesCallerDoubles); }
+
+  void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
+
+  bool requires_frame() const { return GetFlag(kRequiresFrame); }
+
+  void MarkMustNotHaveEagerFrame() { SetFlag(kMustNotHaveEagerFrame); }
+
+  bool GetMustNotHaveEagerFrame() const {
+    return GetFlag(kMustNotHaveEagerFrame);
+  }
+
+  void MarkAsDebug() { SetFlag(kDebug); }
+
+  bool is_debug() const { return GetFlag(kDebug); }
+
+  void PrepareForSerializing() { SetFlag(kSerializing); }
+
+  bool will_serialize() const { return GetFlag(kSerializing); }
+
+  void MarkAsContextSpecializing() { SetFlag(kContextSpecializing); }
+
+  bool is_context_specializing() const { return GetFlag(kContextSpecializing); }
+
+  void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
+
+  void MarkAsInliningDisabled() { SetFlag(kInliningEnabled, false); }
+
+  bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
+
+  void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); }
+
+  bool is_typing_enabled() const { return GetFlag(kTypingEnabled); }
+
+  bool IsCodePreAgingActive() const {
+    return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
+           !is_debug();
+  }
+
+  void SetParseRestriction(ParseRestriction restriction) {
+    SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION);
+  }
+
+  ParseRestriction parse_restriction() const {
+    return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL
+                                      : NO_PARSE_RESTRICTION;
+  }
+
   void SetFunction(FunctionLiteral* literal) {
-    ASSERT(function_ == NULL);
+    DCHECK(function_ == NULL);
     function_ = literal;
   }
-  void SetScope(Scope* scope) {
-    ASSERT(scope_ == NULL);
-    scope_ = scope;
-  }
+  void PrepareForCompilation(Scope* scope);
   void SetGlobalScope(Scope* global_scope) {
-    ASSERT(global_scope_ == NULL);
+    DCHECK(global_scope_ == NULL);
     global_scope_ = global_scope;
   }
+  Handle<TypeFeedbackVector> feedback_vector() const {
+    return feedback_vector_;
+  }
   void SetCode(Handle<Code> code) { code_ = code; }
   void SetExtension(v8::Extension* extension) {
-    ASSERT(!is_lazy());
+    DCHECK(!is_lazy());
     extension_ = extension;
   }
-  void SetPreParseData(ScriptDataImpl* pre_parse_data) {
-    ASSERT(!is_lazy());
-    pre_parse_data_ = pre_parse_data;
-  }
-  void SetCallingContext(Handle<Context> context) {
-    ASSERT(is_eval());
-    calling_context_ = context;
-  }
-  void SetOsrAstId(int osr_ast_id) {
-    ASSERT(IsOptimizing());
-    osr_ast_id_ = osr_ast_id;
-  }
-  void MarkCompilingForDebugging(Handle<Code> current_code) {
-    ASSERT(mode_ != OPTIMIZE);
-    ASSERT(current_code->kind() == Code::FUNCTION);
-    flags_ |= IsCompilingForDebugging::encode(true);
-    if (current_code->is_compiled_optimizable()) {
-      EnableDeoptimizationSupport();
+  void SetCachedData(ScriptData** cached_data,
+                     ScriptCompiler::CompileOptions compile_options) {
+    compile_options_ = compile_options;
+    if (compile_options == ScriptCompiler::kNoCompileOptions) {
+      cached_data_ = NULL;
     } else {
-      mode_ = CompilationInfo::NONOPT;
+      DCHECK(!is_lazy());
+      cached_data_ = cached_data;
     }
   }
-  bool IsCompilingForDebugging() {
-    return IsCompilingForDebugging::decode(flags_);
+  void SetContext(Handle<Context> context) {
+    context_ = context;
+  }
+
+  void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); }
+  bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); }
+  void MarkNonOptimizable() {
+    SetMode(CompilationInfo::NONOPT);
+  }
+
+  bool ShouldTrapOnDeopt() const {
+    return (FLAG_trap_on_deopt && IsOptimizing()) ||
+        (FLAG_trap_on_stub_deopt && IsStub());
   }
 
   bool has_global_object() const {
-    return !closure().is_null() && (closure()->context()->global() != NULL);
+    return !closure().is_null() &&
+        (closure()->context()->global_object() != NULL);
   }
 
   GlobalObject* global_object() const {
-    return has_global_object() ? closure()->context()->global() : NULL;
+    return has_global_object() ? closure()->context()->global_object() : NULL;
   }
 
   // Accessors for the different compilation modes.
   bool IsOptimizing() const { return mode_ == OPTIMIZE; }
   bool IsOptimizable() const { return mode_ == BASE; }
-  void SetOptimizing(int osr_ast_id) {
+  bool IsStub() const { return mode_ == STUB; }
+  void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) {
+    DCHECK(!shared_info_.is_null());
     SetMode(OPTIMIZE);
     osr_ast_id_ = osr_ast_id;
+    unoptimized_code_ = unoptimized;
+    optimization_id_ = isolate()->NextOptimizationId();
   }
-  void DisableOptimization();
 
   // Deoptimization support.
   bool HasDeoptimizationSupport() const {
-    return SupportsDeoptimization::decode(flags_);
+    return GetFlag(kDeoptimizationSupport);
   }
   void EnableDeoptimizationSupport() {
-    ASSERT(IsOptimizable());
-    flags_ |= SupportsDeoptimization::encode(true);
+    DCHECK(IsOptimizable());
+    SetFlag(kDeoptimizationSupport);
   }
 
   // Determines whether or not to insert a self-optimization header.
   bool ShouldSelfOptimize();
 
-  // Disable all optimization attempts of this info for the rest of the
-  // current compilation pipeline.
-  void AbortOptimization();
+  void set_deferred_handles(DeferredHandles* deferred_handles) {
+    DCHECK(deferred_handles_ == NULL);
+    deferred_handles_ = deferred_handles;
+  }
+
+  ZoneList<Handle<HeapObject> >* dependencies(
+      DependentCode::DependencyGroup group) {
+    if (dependencies_[group] == NULL) {
+      dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_);
+    }
+    return dependencies_[group];
+  }
+
+  void CommitDependencies(Handle<Code> code);
+
+  void RollbackDependencies();
+
+  void SaveHandles() {
+    SaveHandle(&closure_);
+    SaveHandle(&shared_info_);
+    SaveHandle(&context_);
+    SaveHandle(&script_);
+    SaveHandle(&unoptimized_code_);
+  }
+
+  void AbortOptimization(BailoutReason reason) {
+    if (bailout_reason_ != kNoReason) bailout_reason_ = reason;
+    SetFlag(kDisableFutureOptimization);
+  }
+
+  void RetryOptimization(BailoutReason reason) {
+    if (bailout_reason_ != kNoReason) bailout_reason_ = reason;
+  }
+
+  BailoutReason bailout_reason() const { return bailout_reason_; }
+
+  int prologue_offset() const {
+    DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
+    return prologue_offset_;
+  }
+
+  void set_prologue_offset(int prologue_offset) {
+    DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
+    prologue_offset_ = prologue_offset;
+  }
+
+  // Adds offset range [from, to) where fp register does not point
+  // to the current frame base. Used in CPU profiler to detect stack
+  // samples where top frame is not set up.
+  inline void AddNoFrameRange(int from, int to) {
+    if (no_frame_ranges_) no_frame_ranges_->Add(OffsetRange(from, to));
+  }
+
+  List<OffsetRange>* ReleaseNoFrameRanges() {
+    List<OffsetRange>* result = no_frame_ranges_;
+    no_frame_ranges_ = NULL;
+    return result;
+  }
+
+  Handle<Foreign> object_wrapper() {
+    if (object_wrapper_.is_null()) {
+      object_wrapper_ =
+          isolate()->factory()->NewForeign(reinterpret_cast<Address>(this));
+    }
+    return object_wrapper_;
+  }
+
+  void AbortDueToDependencyChange() {
+    DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
+    aborted_due_to_dependency_change_ = true;
+  }
+
+  bool HasAbortedDueToDependencyChange() const {
+    DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
+    return aborted_due_to_dependency_change_;
+  }
+
+  bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) {
+    return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_);
+  }
+
+  int optimization_id() const { return optimization_id_; }
+
+  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
+  void SetAstValueFactory(AstValueFactory* ast_value_factory,
+                          bool owned = true) {
+    ast_value_factory_ = ast_value_factory;
+    ast_value_factory_owned_ = owned;
+  }
+
+  AstNode::IdGen* ast_node_id_gen() { return &ast_node_id_gen_; }
+
+ protected:
+  CompilationInfo(Handle<Script> script,
+                  Zone* zone);
+  CompilationInfo(Handle<SharedFunctionInfo> shared_info,
+                  Zone* zone);
+  CompilationInfo(HydrogenCodeStub* stub,
+                  Isolate* isolate,
+                  Zone* zone);
+  CompilationInfo(ScriptCompiler::ExternalSourceStream* source_stream,
+                  ScriptCompiler::StreamedSource::Encoding encoding,
+                  Isolate* isolate, Zone* zone);
+
 
  private:
   Isolate* isolate_;
@@ -181,48 +412,23 @@
   enum Mode {
     BASE,
     OPTIMIZE,
-    NONOPT
+    NONOPT,
+    STUB
   };
 
-  CompilationInfo() : function_(NULL) {}
-
-  void Initialize(Mode mode) {
-    mode_ = V8::UseCrankshaft() ? mode : NONOPT;
-    ASSERT(!script_.is_null());
-    if (script_->type()->value() == Script::TYPE_NATIVE) {
-      MarkAsNative();
-    }
-    if (!shared_info_.is_null()) {
-      ASSERT(language_mode() == CLASSIC_MODE);
-      SetLanguageMode(shared_info_->language_mode());
-    }
-  }
+  void Initialize(Isolate* isolate, Mode mode, Zone* zone);
 
   void SetMode(Mode mode) {
-    ASSERT(V8::UseCrankshaft());
     mode_ = mode;
   }
 
-  // Flags using template class BitField<type, start, length>.  All are
-  // false by default.
-  //
-  // Compilation is either eager or lazy.
-  class IsLazy:   public BitField<bool, 0, 1> {};
-  // Flags that can be set for eager compilation.
-  class IsEval:   public BitField<bool, 1, 1> {};
-  class IsGlobal: public BitField<bool, 2, 1> {};
-  // Flags that can be set for lazy compilation.
-  class IsInLoop: public BitField<bool, 3, 1> {};
-  // Strict mode - used in eager compilation.
-  class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
-  // Is this a function from our natives.
-  class IsNative: public BitField<bool, 6, 1> {};
-  // Is this code being compiled with support for deoptimization..
-  class SupportsDeoptimization: public BitField<bool, 7, 1> {};
-  // If compiling for debugging produce just full code matching the
-  // initial mode setting.
-  class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
+  void SetFlag(Flag flag) { flags_ |= flag; }
 
+  void SetFlag(Flag flag, bool value) {
+    flags_ = value ? flags_ | flag : flags_ & ~flag;
+  }
+
+  bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
 
   unsigned flags_;
 
@@ -234,6 +440,8 @@
   Scope* scope_;
   // The global scope provided as a convenience.
   Scope* global_scope_;
+  // For compiled stubs, the stub object
+  HydrogenCodeStub* code_stub_;
   // The compiled code.
   Handle<Code> code_;
 
@@ -241,23 +449,208 @@
   Handle<JSFunction> closure_;
   Handle<SharedFunctionInfo> shared_info_;
   Handle<Script> script_;
+  ScriptCompiler::ExternalSourceStream* source_stream_;  // Not owned.
+  ScriptCompiler::StreamedSource::Encoding source_stream_encoding_;
 
   // Fields possibly needed for eager compilation, NULL by default.
   v8::Extension* extension_;
-  ScriptDataImpl* pre_parse_data_;
+  ScriptData** cached_data_;
+  ScriptCompiler::CompileOptions compile_options_;
 
-  // The context of the caller is needed for eval code, and will be a null
-  // handle otherwise.
-  Handle<Context> calling_context_;
+  // The context of the caller for eval code, and the global context for a
+  // global script. Will be a null handle otherwise.
+  Handle<Context> context_;
+
+  // Used by codegen, ultimately kept rooted by the SharedFunctionInfo.
+  Handle<TypeFeedbackVector> feedback_vector_;
 
   // Compilation mode flag and whether deoptimization is allowed.
   Mode mode_;
-  int osr_ast_id_;
+  BailoutId osr_ast_id_;
+  // The unoptimized code we patched for OSR may not be the shared code
+  // afterwards, since we may need to compile it again to include deoptimization
+  // data.  Keep track which code we patched.
+  Handle<Code> unoptimized_code_;
+
+  // The zone from which the compilation pipeline working on this
+  // CompilationInfo allocates.
+  Zone* zone_;
+
+  DeferredHandles* deferred_handles_;
+
+  ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount];
+
+  template<typename T>
+  void SaveHandle(Handle<T> *object) {
+    if (!object->is_null()) {
+      Handle<T> handle(*(*object));
+      *object = handle;
+    }
+  }
+
+  BailoutReason bailout_reason_;
+
+  int prologue_offset_;
+
+  List<OffsetRange>* no_frame_ranges_;
+
+  // A copy of shared_info()->opt_count() to avoid handle deref
+  // during graph optimization.
+  int opt_count_;
+
+  // Number of parameters used for compilation of stubs that require arguments.
+  int parameter_count_;
+
+  Handle<Foreign> object_wrapper_;
+
+  int optimization_id_;
+
+  AstValueFactory* ast_value_factory_;
+  bool ast_value_factory_owned_;
+  AstNode::IdGen ast_node_id_gen_;
+
+  // This flag is used by the main thread to track whether this compilation
+  // should be abandoned due to dependency change.
+  bool aborted_due_to_dependency_change_;
 
   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
 };
 
 
+// Exactly like a CompilationInfo, except also creates and enters a
+// Zone on construction and deallocates it on exit.
+class CompilationInfoWithZone: public CompilationInfo {
+ public:
+  explicit CompilationInfoWithZone(Handle<Script> script)
+      : CompilationInfo(script, &zone_),
+        zone_(script->GetIsolate()) {}
+  explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)
+      : CompilationInfo(shared_info, &zone_),
+        zone_(shared_info->GetIsolate()) {}
+  explicit CompilationInfoWithZone(Handle<JSFunction> closure)
+      : CompilationInfo(closure, &zone_),
+        zone_(closure->GetIsolate()) {}
+  CompilationInfoWithZone(HydrogenCodeStub* stub, Isolate* isolate)
+      : CompilationInfo(stub, isolate, &zone_),
+        zone_(isolate) {}
+  CompilationInfoWithZone(ScriptCompiler::ExternalSourceStream* stream,
+                          ScriptCompiler::StreamedSource::Encoding encoding,
+                          Isolate* isolate)
+      : CompilationInfo(stream, encoding, isolate, &zone_), zone_(isolate) {}
+
+  // Virtual destructor because a CompilationInfoWithZone has to exit the
+  // zone scope and get rid of dependent maps even when the destructor is
+  // called when cast as a CompilationInfo.
+  virtual ~CompilationInfoWithZone() {
+    RollbackDependencies();
+  }
+
+ private:
+  Zone zone_;
+};
+
+
+// A wrapper around a CompilationInfo that detaches the Handles from
+// the underlying DeferredHandleScope and stores them in info_ on
+// destruction.
+class CompilationHandleScope BASE_EMBEDDED {
+ public:
+  explicit CompilationHandleScope(CompilationInfo* info)
+      : deferred_(info->isolate()), info_(info) {}
+  ~CompilationHandleScope() {
+    info_->set_deferred_handles(deferred_.Detach());
+  }
+
+ private:
+  DeferredHandleScope deferred_;
+  CompilationInfo* info_;
+};
+
+
+class HGraph;
+class HOptimizedGraphBuilder;
+class LChunk;
+
+// A helper class that calls the three compilation phases in
+// Crankshaft and keeps track of its state.  The three phases
+// CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
+// fail, bail-out to the full code generator or succeed.  Apart from
+// their return value, the status of the phase last run can be checked
+// using last_status().
+class OptimizedCompileJob: public ZoneObject {
+ public:
+  explicit OptimizedCompileJob(CompilationInfo* info)
+      : info_(info),
+        graph_builder_(NULL),
+        graph_(NULL),
+        chunk_(NULL),
+        last_status_(FAILED),
+        awaiting_install_(false) { }
+
+  enum Status {
+    FAILED, BAILED_OUT, SUCCEEDED
+  };
+
+  MUST_USE_RESULT Status CreateGraph();
+  MUST_USE_RESULT Status OptimizeGraph();
+  MUST_USE_RESULT Status GenerateCode();
+
+  Status last_status() const { return last_status_; }
+  CompilationInfo* info() const { return info_; }
+  Isolate* isolate() const { return info()->isolate(); }
+
+  Status RetryOptimization(BailoutReason reason) {
+    info_->RetryOptimization(reason);
+    return SetLastStatus(BAILED_OUT);
+  }
+
+  Status AbortOptimization(BailoutReason reason) {
+    info_->AbortOptimization(reason);
+    return SetLastStatus(BAILED_OUT);
+  }
+
+  void WaitForInstall() {
+    DCHECK(info_->is_osr());
+    awaiting_install_ = true;
+  }
+
+  bool IsWaitingForInstall() { return awaiting_install_; }
+
+ private:
+  CompilationInfo* info_;
+  HOptimizedGraphBuilder* graph_builder_;
+  HGraph* graph_;
+  LChunk* chunk_;
+  base::TimeDelta time_taken_to_create_graph_;
+  base::TimeDelta time_taken_to_optimize_;
+  base::TimeDelta time_taken_to_codegen_;
+  Status last_status_;
+  bool awaiting_install_;
+
+  MUST_USE_RESULT Status SetLastStatus(Status status) {
+    last_status_ = status;
+    return last_status_;
+  }
+  void RecordOptimizationStats();
+
+  struct Timer {
+    Timer(OptimizedCompileJob* job, base::TimeDelta* location)
+        : job_(job), location_(location) {
+      DCHECK(location_ != NULL);
+      timer_.Start();
+    }
+
+    ~Timer() {
+      *location_ += timer_.Elapsed();
+    }
+
+    OptimizedCompileJob* job_;
+    base::ElapsedTimer timer_;
+    base::TimeDelta* location_;
+  };
+};
+
+
 // The V8 compiler
 //
 // General strategy: Source code is translated into an anonymous function w/o
@@ -271,61 +664,87 @@
 
 class Compiler : public AllStatic {
  public:
-  // Default maximum number of function optimization attempts before we
-  // give up.
-  static const int kDefaultMaxOptCount = 10;
+  MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
+      Handle<JSFunction> function);
+  MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode(
+      Handle<JSFunction> function);
+  MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
+      Handle<SharedFunctionInfo> shared);
+  MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode(
+      Handle<JSFunction> function);
 
-  static const int kMaxInliningLevels = 3;
+  static bool EnsureCompiled(Handle<JSFunction> function,
+                             ClearExceptionFlag flag);
 
-  // Call count before primitive functions trigger their own optimization.
-  static const int kCallsUntilPrimitiveOpt = 200;
+  static bool EnsureDeoptimizationSupport(CompilationInfo* info);
 
-  // All routines return a SharedFunctionInfo.
-  // If an error occurs an exception is raised and the return handle
-  // contains NULL.
+  static void CompileForLiveEdit(Handle<Script> script);
+
+  // Compile a String source within a context for eval.
+  MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
+      Handle<String> source, Handle<SharedFunctionInfo> outer_info,
+      Handle<Context> context, StrictMode strict_mode,
+      ParseRestriction restriction, int scope_position);
 
   // Compile a String source within a context.
-  static Handle<SharedFunctionInfo> Compile(Handle<String> source,
-                                            Handle<Object> script_name,
-                                            int line_offset,
-                                            int column_offset,
-                                            v8::Extension* extension,
-                                            ScriptDataImpl* pre_data,
-                                            Handle<Object> script_data,
-                                            NativesFlag is_natives_code);
+  static Handle<SharedFunctionInfo> CompileScript(
+      Handle<String> source, Handle<Object> script_name, int line_offset,
+      int column_offset, bool is_shared_cross_origin, Handle<Context> context,
+      v8::Extension* extension, ScriptData** cached_data,
+      ScriptCompiler::CompileOptions compile_options,
+      NativesFlag is_natives_code);
 
-  // Compile a String source within a context for Eval.
-  static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
-                                                Handle<Context> context,
-                                                bool is_global,
-                                                LanguageMode language_mode,
-                                                int scope_position);
+  static Handle<SharedFunctionInfo> CompileStreamedScript(CompilationInfo* info,
+                                                          int source_length);
 
-  // Compile from function info (used for lazy compilation). Returns true on
-  // success and false if the compilation resulted in a stack overflow.
-  static bool CompileLazy(CompilationInfo* info);
-
-  // Compile a shared function info object (the function is possibly lazily
-  // compiled).
+  // Create a shared function info object (the code may be lazily compiled).
   static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
-                                                      Handle<Script> script);
+                                                      Handle<Script> script,
+                                                      CompilationInfo* outer);
 
-  // Set the function info for a newly compiled function.
-  static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
-                              FunctionLiteral* lit,
-                              bool is_toplevel,
-                              Handle<Script> script);
+  enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
 
-#ifdef ENABLE_DEBUGGER_SUPPORT
-  static bool MakeCodeForLiveEdit(CompilationInfo* info);
-#endif
+  // Generate and return optimized code or start a concurrent optimization job.
+  // In the latter case, return the InOptimizationQueue builtin.  On failure,
+  // return the empty handle.
+  MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode(
+      Handle<JSFunction> function,
+      Handle<Code> current_code,
+      ConcurrencyMode mode,
+      BailoutId osr_ast_id = BailoutId::None());
 
-  static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
-                                        CompilationInfo* info,
-                                        Handle<SharedFunctionInfo> shared);
+  // Generate and return code from previously queued optimization job.
+  // On failure, return the empty handle.
+  static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job);
+
+  static bool DebuggerWantsEagerCompilation(
+      CompilationInfo* info, bool allow_lazy_without_ctx = false);
 };
 
 
+class CompilationPhase BASE_EMBEDDED {
+ public:
+  CompilationPhase(const char* name, CompilationInfo* info);
+  ~CompilationPhase();
+
+ protected:
+  bool ShouldProduceTraceOutput() const;
+
+  const char* name() const { return name_; }
+  CompilationInfo* info() const { return info_; }
+  Isolate* isolate() const { return info()->isolate(); }
+  Zone* zone() { return &zone_; }
+
+ private:
+  const char* name_;
+  CompilationInfo* info_;
+  Zone zone_;
+  unsigned info_zone_start_allocation_size_;
+  base::ElapsedTimer timer_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompilationPhase);
+};
+
 } }  // namespace v8::internal
 
 #endif  // V8_COMPILER_H_
