Merge V8 at 3.9.24.29

Bug: 6552361
Change-Id: Ic75bc91849fed7b20846e9c10e2c1ffcc5239da5
diff --git a/src/compiler.cc b/src/compiler.cc
index c9c2480..ecac5cb 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -118,7 +118,7 @@
       FLAG_crankshaft &&
       !function()->flags()->Contains(kDontSelfOptimize) &&
       !function()->flags()->Contains(kDontOptimize) &&
-      function()->scope()->allows_lazy_recompilation() &&
+      function()->scope()->AllowsLazyRecompilation() &&
       (shared_info().is_null() || !shared_info()->optimization_disabled());
 }
 
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 531eed2..44fe011 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -314,7 +314,8 @@
   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
   Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
   code->set_optimizable(info->IsOptimizable() &&
-                        !info->function()->flags()->Contains(kDontOptimize));
+                        !info->function()->flags()->Contains(kDontOptimize) &&
+                        info->function()->scope()->AllowsLazyRecompilation());
   code->set_self_optimization_header(cgen.has_self_optimization_header_);
   cgen.PopulateDeoptimizationData(code);
   cgen.PopulateTypeFeedbackInfo(code);
diff --git a/src/scopes.cc b/src/scopes.cc
index 859cbd1..c142c3d 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -649,6 +649,26 @@
 }
 
 
+bool Scope::AllowsLazyRecompilation() const {
+  return !force_eager_compilation_ &&
+         !TrivialDeclarationScopesBeforeWithScope();
+}
+
+
+bool Scope::TrivialDeclarationScopesBeforeWithScope() const {
+  Scope* outer = outer_scope_;
+  if (outer == NULL) return false;
+  outer = outer->DeclarationScope();
+  while (outer != NULL) {
+    if (outer->is_with_scope()) return true;
+    if (outer->is_declaration_scope() && outer->num_heap_slots() > 0)
+      return false;
+    outer = outer->outer_scope_;
+  }
+  return false;
+}
+
+
 int Scope::ContextChainLength(Scope* scope) {
   int n = 0;
   for (Scope* s = this; s != scope; s = s->outer_scope_) {
diff --git a/src/scopes.h b/src/scopes.h
index d315b7e..174dbdb 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -369,13 +369,16 @@
   bool AllowsLazyCompilation() const;
 
   // True if we can lazily recompile functions with this scope.
-  bool allows_lazy_recompilation() const {
-    return !force_eager_compilation_;
-  }
+  bool AllowsLazyRecompilation() const;
 
   // True if the outer context of this scope is always the global context.
   bool HasTrivialOuterContext() const;
 
+  // True if this scope is inside a with scope and all declaration scopes
+  // between them have empty contexts. Such declaration scopes become
+  // invisible during scope info deserialization.
+  bool TrivialDeclarationScopesBeforeWithScope() const;
+
   // The number of contexts between this and scope; zero if this == scope.
   int ContextChainLength(Scope* scope);
 
diff --git a/src/version.cc b/src/version.cc
index 558c4ac..25769f2 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     9
 #define BUILD_NUMBER      24
-#define PATCH_LEVEL       28
+#define PATCH_LEVEL       29
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0