Revision: 13215
Author: [email protected]
Date: Thu Dec 13 05:20:46 2012
Log: Merged r13161 into 3.14 branch.
Allow lazy compilation (and thus optimisation) of functions inside eval.
BUG=v8:2315
[email protected]
Review URL: https://codereview.chromium.org/11564012
http://code.google.com/p/v8/source/detail?r=13215
Added:
/branches/3.14/test/mjsunit/regress/regress-2315.js
Modified:
/branches/3.14/src/contexts.h
/branches/3.14/src/lithium.h
/branches/3.14/src/parser.cc
/branches/3.14/src/preparser.h
/branches/3.14/src/scopes.cc
/branches/3.14/src/version.cc
/branches/3.14/test/mjsunit/regress/regress-492.js
/branches/3.14/test/mjsunit/regress/regress-crbug-135066.js
=======================================
--- /dev/null
+++ /branches/3.14/test/mjsunit/regress/regress-2315.js Thu Dec 13 05:20:46
2012
@@ -0,0 +1,40 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+var foo = (function() {
+ return eval("(function bar() { return 1; })");
+})();
+
+foo();
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
+
+// Function should be optimized now.
+assertTrue(%GetOptimizationStatus(foo) != 2);
=======================================
--- /branches/3.14/src/contexts.h Thu Sep 20 05:51:09 2012
+++ /branches/3.14/src/contexts.h Thu Dec 13 05:20:46 2012
@@ -344,9 +344,13 @@
// Compute the native context by traversing the context chain.
Context* native_context();
- // Predicates for context types. IsNativeContext is defined on Object
+ // Predicates for context types. IsNativeContext is also defined on
Object
// because we frequently have to know if arbitrary objects are natives
// contexts.
+ bool IsNativeContext() {
+ Map* map = this->map();
+ return map == map->GetHeap()->native_context_map();
+ }
bool IsFunctionContext() {
Map* map = this->map();
return map == map->GetHeap()->function_context_map();
=======================================
--- /branches/3.14/src/lithium.h Wed Oct 10 10:07:22 2012
+++ /branches/3.14/src/lithium.h Thu Dec 13 05:20:46 2012
@@ -156,8 +156,8 @@
};
static const int kMaxVirtualRegisters = 1 << kVirtualRegisterWidth;
- static const int kMaxFixedIndex = (1 << kFixedIndexWidth) - 1;
- static const int kMinFixedIndex = -(1 << kFixedIndexWidth);
+ static const int kMaxFixedIndex = (1 << (kFixedIndexWidth - 1)) - 1;
+ static const int kMinFixedIndex = -(1 << (kFixedIndexWidth - 1));
bool HasAnyPolicy() const {
return policy() == ANY;
=======================================
--- /branches/3.14/src/parser.cc Wed Oct 10 10:07:22 2012
+++ /branches/3.14/src/parser.cc Thu Dec 13 05:20:46 2012
@@ -614,11 +614,6 @@
ASSERT(target_stack_ == NULL);
if (pre_data_ != NULL) pre_data_->Initialize();
- // Compute the parsing mode.
- Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
- if (allow_natives_syntax_ || extension_ != NULL) mode = PARSE_EAGERLY;
- ParsingModeScope parsing_mode(this, mode);
-
Handle<String> no_name = isolate()->factory()->empty_symbol();
FunctionLiteral* result = NULL;
@@ -637,6 +632,13 @@
scope->set_start_position(0);
scope->set_end_position(source->length());
+ // Compute the parsing mode.
+ Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
+ if (allow_natives_syntax_ || extension_ != NULL ||
scope->is_eval_scope()) {
+ mode = PARSE_EAGERLY;
+ }
+ ParsingModeScope parsing_mode(this, mode);
+
FunctionState function_state(this, scope, isolate()); //
Enters 'scope'.
top_scope_->SetLanguageMode(info->language_mode());
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16,
zone());
@@ -1059,12 +1061,14 @@
// as specified in ES5 10.4.2(3). The correct fix would be to
always
// add this scope in DoParseProgram(), but that requires
adaptations
// all over the code base, so we go with a quick-fix for now.
+ // In the same manner, we have to patch the parsing mode.
if (is_eval && !top_scope_->is_eval_scope()) {
ASSERT(top_scope_->is_global_scope());
Scope* scope = NewScope(top_scope_, EVAL_SCOPE);
scope->set_start_position(top_scope_->start_position());
scope->set_end_position(top_scope_->end_position());
top_scope_ = scope;
+ mode_ = PARSE_EAGERLY;
}
// TODO(ES6): Fix entering extended mode, once it is specified.
top_scope_->SetLanguageMode(FLAG_harmony_scoping
=======================================
--- /branches/3.14/src/preparser.h Thu May 3 02:06:43 2012
+++ /branches/3.14/src/preparser.h Thu Dec 13 05:20:46 2012
@@ -150,11 +150,11 @@
// Parses a single function literal, from the opening parentheses before
// parameters to the closing brace after the body.
- // Returns a FunctionEntry describing the body of the funciton in enough
+ // Returns a FunctionEntry describing the body of the function in enough
// detail that it can be lazily compiled.
// The scanner is expected to have matched the "function" keyword and
// parameters, and have consumed the initial '{'.
- // At return, unless an error occured, the scanner is positioned before
the
+ // At return, unless an error occurred, the scanner is positioned before
the
// the final '}'.
PreParseResult PreParseLazyFunction(i::LanguageMode mode,
i::ParserRecorder* log);
=======================================
--- /branches/3.14/src/scopes.cc Wed Aug 29 08:32:24 2012
+++ /branches/3.14/src/scopes.cc Thu Dec 13 05:20:46 2012
@@ -702,17 +702,12 @@
bool Scope::HasLazyCompilableOuterContext() const {
Scope* outer = outer_scope_;
if (outer == NULL) return true;
- // There are several reasons that prevent lazy compilation:
- // - 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.
- // - This scope is inside a strict eval scope with variables that are
- // potentially context allocated in an artificial function scope that
- // is not deserialized correctly.
+ // We have to prevent lazy compilation if this scope is inside a with
scope
+ // and all declaration scopes between them have empty contexts. Such
+ // declaration scopes may become invisible during scope info
deserialization.
outer = outer->DeclarationScope();
bool found_non_trivial_declarations = false;
for (const Scope* scope = outer; scope != NULL; scope =
scope->outer_scope_) {
- if (scope->is_eval_scope()) return false;
if (scope->is_with_scope() && !found_non_trivial_declarations) return
false;
if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
found_non_trivial_declarations = true;
=======================================
--- /branches/3.14/src/version.cc Tue Nov 20 01:11:03 2012
+++ /branches/3.14/src/version.cc Thu Dec 13 05:20:46 2012
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 14
#define BUILD_NUMBER 5
-#define PATCH_LEVEL 2
+#define PATCH_LEVEL 3
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.14/test/mjsunit/regress/regress-492.js Wed Nov 18 06:12:51
2009
+++ /branches/3.14/test/mjsunit/regress/regress-492.js Thu Dec 13 05:20:46
2012
@@ -29,7 +29,7 @@
// This should not hit any asserts in debug mode on ARM.
function function_with_n_args(n) {
- var source = '(function f(';
+ var source = '(function f' + n + '(';
for (var arg = 0; arg < n; arg++) {
if (arg != 0) source += ',';
source += 'arg' + arg;
@@ -50,3 +50,41 @@
for (args = 1019; args < 1041; args++) {
function_with_n_args(args);
}
+
+
+function foo(
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
+) {}
+
+for (var i = 0; i < 10000; ++i) foo();
=======================================
--- /branches/3.14/test/mjsunit/regress/regress-crbug-135066.js Tue Jul 3
03:03:19 2012
+++ /branches/3.14/test/mjsunit/regress/regress-crbug-135066.js Thu Dec 13
05:20:46 2012
@@ -29,25 +29,27 @@
var filler = "//" + new Array(1024).join('x');
// Test strict eval in global context.
-eval(
+assertEquals(23, eval(
"'use strict';" +
"var x = 23;" +
"var f = function bozo1() {" +
" return x;" +
"};" +
"assertSame(23, f());" +
+ "f;" +
filler
-);
+)());
// Test default eval in strict context.
-(function() {
+assertEquals(42, (function() {
"use strict";
- eval(
+ return eval(
"var y = 42;" +
"var g = function bozo2() {" +
" return y;" +
"};" +
"assertSame(42, g());" +
+ "g;" +
filler
- );
-})();
+ )();
+})());
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev