Commit c52b7bba authored by yangguo@chromium.org's avatar yangguo@chromium.org

Fix regressions triggered by map invalidation during graph creation.

BUG=
R=jkummerow@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16150 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 514dd034
...@@ -41,6 +41,7 @@ enum PerThreadAssertType { ...@@ -41,6 +41,7 @@ enum PerThreadAssertType {
HANDLE_ALLOCATION_ASSERT, HANDLE_ALLOCATION_ASSERT,
HANDLE_DEREFERENCE_ASSERT, HANDLE_DEREFERENCE_ASSERT,
DEFERRED_HANDLE_DEREFERENCE_ASSERT, DEFERRED_HANDLE_DEREFERENCE_ASSERT,
CODE_DEPENDENCY_CHANGE_ASSERT,
LAST_PER_THREAD_ASSERT_TYPE LAST_PER_THREAD_ASSERT_TYPE
}; };
...@@ -170,6 +171,14 @@ typedef PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false> ...@@ -170,6 +171,14 @@ typedef PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>
typedef PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true> typedef PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>
AllowDeferredHandleDereference; AllowDeferredHandleDereference;
// Scope to document where we do not expect deferred handles to be dereferenced.
typedef PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>
DisallowCodeDependencyChange;
// Scope to introduce an exception to DisallowDeferredHandleDereference.
typedef PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>
AllowCodeDependencyChange;
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_ASSERT_SCOPE_H_ #endif // V8_ASSERT_SCOPE_H_
...@@ -120,6 +120,7 @@ void CompilationInfo::Initialize(Isolate* isolate, ...@@ -120,6 +120,7 @@ void CompilationInfo::Initialize(Isolate* isolate,
return; return;
} }
mode_ = V8::UseCrankshaft() ? mode : NONOPT; mode_ = V8::UseCrankshaft() ? mode : NONOPT;
abort_due_to_dependency_ = false;
if (script_->type()->value() == Script::TYPE_NATIVE) { if (script_->type()->value() == Script::TYPE_NATIVE) {
MarkAsNative(); MarkAsNative();
} }
...@@ -446,6 +447,12 @@ OptimizingCompiler::Status OptimizingCompiler::CreateGraph() { ...@@ -446,6 +447,12 @@ OptimizingCompiler::Status OptimizingCompiler::CreateGraph() {
} }
} }
if (info()->HasAbortedDueToDependencyChange()) {
info_->set_bailout_reason(kBailedOutDueToDependencyChange);
info_->AbortOptimization();
return SetLastStatus(BAILED_OUT);
}
return SetLastStatus(SUCCEEDED); return SetLastStatus(SUCCEEDED);
} }
...@@ -454,6 +461,7 @@ OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() { ...@@ -454,6 +461,7 @@ OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
DisallowHandleAllocation no_handles; DisallowHandleAllocation no_handles;
DisallowHandleDereference no_deref; DisallowHandleDereference no_deref;
DisallowCodeDependencyChange no_dependency_change;
ASSERT(last_status() == SUCCEEDED); ASSERT(last_status() == SUCCEEDED);
Timer t(this, &time_taken_to_optimize_); Timer t(this, &time_taken_to_optimize_);
...@@ -474,6 +482,8 @@ OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() { ...@@ -474,6 +482,8 @@ OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() {
OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() { OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() {
ASSERT(last_status() == SUCCEEDED); ASSERT(last_status() == SUCCEEDED);
ASSERT(!info()->HasAbortedDueToDependencyChange());
DisallowCodeDependencyChange no_dependency_change;
{ // Scope for timer. { // Scope for timer.
Timer timer(this, &time_taken_to_codegen_); Timer timer(this, &time_taken_to_codegen_);
ASSERT(chunk_ != NULL); ASSERT(chunk_ != NULL);
...@@ -815,6 +825,7 @@ static bool InstallFullCode(CompilationInfo* info) { ...@@ -815,6 +825,7 @@ static bool InstallFullCode(CompilationInfo* info) {
// was flushed. By setting the code object last we avoid this. // was flushed. By setting the code object last we avoid this.
Handle<SharedFunctionInfo> shared = info->shared_info(); Handle<SharedFunctionInfo> shared = info->shared_info();
Handle<Code> code = info->code(); Handle<Code> code = info->code();
CHECK(code->kind() == Code::FUNCTION);
Handle<JSFunction> function = info->closure(); Handle<JSFunction> function = info->closure();
Handle<ScopeInfo> scope_info = Handle<ScopeInfo> scope_info =
ScopeInfo::Create(info->scope(), info->zone()); ScopeInfo::Create(info->scope(), info->zone());
...@@ -1059,7 +1070,7 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) { ...@@ -1059,7 +1070,7 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
// the unoptimized code. // the unoptimized code.
OptimizingCompiler::Status status = optimizing_compiler->last_status(); OptimizingCompiler::Status status = optimizing_compiler->last_status();
if (info->HasAbortedDueToDependencyChange()) { if (info->HasAbortedDueToDependencyChange()) {
info->set_bailout_reason(kBailedOutDueToDependentMap); info->set_bailout_reason(kBailedOutDueToDependencyChange);
status = optimizing_compiler->AbortOptimization(); status = optimizing_compiler->AbortOptimization();
} else if (status != OptimizingCompiler::SUCCEEDED) { } else if (status != OptimizingCompiler::SUCCEEDED) {
info->set_bailout_reason(kFailedBailedOutLastTime); info->set_bailout_reason(kFailedBailedOutLastTime);
......
...@@ -298,11 +298,13 @@ class CompilationInfo { ...@@ -298,11 +298,13 @@ class CompilationInfo {
} }
void AbortDueToDependencyChange() { void AbortDueToDependencyChange() {
mode_ = DEPENDENCY_CHANGE_ABORT; ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
abort_due_to_dependency_ = true;
} }
bool HasAbortedDueToDependencyChange() { bool HasAbortedDueToDependencyChange() {
return mode_ == DEPENDENCY_CHANGE_ABORT; ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
return abort_due_to_dependency_;
} }
protected: protected:
...@@ -326,8 +328,7 @@ class CompilationInfo { ...@@ -326,8 +328,7 @@ class CompilationInfo {
BASE, BASE,
OPTIMIZE, OPTIMIZE,
NONOPT, NONOPT,
STUB, STUB
DEPENDENCY_CHANGE_ABORT
}; };
void Initialize(Isolate* isolate, Mode mode, Zone* zone); void Initialize(Isolate* isolate, Mode mode, Zone* zone);
...@@ -401,6 +402,9 @@ class CompilationInfo { ...@@ -401,6 +402,9 @@ class CompilationInfo {
Mode mode_; Mode mode_;
BailoutId osr_ast_id_; BailoutId osr_ast_id_;
// Flag whether compilation needs to be aborted due to dependency change.
bool abort_due_to_dependency_;
// The zone from which the compilation pipeline working on this // The zone from which the compilation pipeline working on this
// CompilationInfo allocates. // CompilationInfo allocates.
Zone* zone_; Zone* zone_;
......
...@@ -11354,6 +11354,7 @@ bool DependentCode::Contains(DependencyGroup group, Code* code) { ...@@ -11354,6 +11354,7 @@ bool DependentCode::Contains(DependencyGroup group, Code* code) {
void DependentCode::DeoptimizeDependentCodeGroup( void DependentCode::DeoptimizeDependentCodeGroup(
Isolate* isolate, Isolate* isolate,
DependentCode::DependencyGroup group) { DependentCode::DependencyGroup group) {
ASSERT(AllowCodeDependencyChange::IsAllowed());
DisallowHeapAllocation no_allocation_scope; DisallowHeapAllocation no_allocation_scope;
DependentCode::GroupStartIndexes starts(this); DependentCode::GroupStartIndexes starts(this);
int start = starts.at(group); int start = starts.at(group);
......
...@@ -1076,7 +1076,7 @@ class MaybeObject BASE_EMBEDDED { ...@@ -1076,7 +1076,7 @@ class MaybeObject BASE_EMBEDDED {
"bad value context for arguments object value") \ "bad value context for arguments object value") \
V(kBadValueContextForArgumentsValue, \ V(kBadValueContextForArgumentsValue, \
"bad value context for arguments value") \ "bad value context for arguments value") \
V(kBailedOutDueToDependentMap, "bailed out due to dependent map") \ V(kBailedOutDueToDependencyChange, "bailed out due to dependency change") \
V(kBailoutWasNotPrepared, "bailout was not prepared") \ V(kBailoutWasNotPrepared, "bailout was not prepared") \
V(kBinaryStubGenerateFloatingPointCode, \ V(kBinaryStubGenerateFloatingPointCode, \
"BinaryStub_GenerateFloatingPointCode") \ "BinaryStub_GenerateFloatingPointCode") \
......
// Copyright 2013 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 c = { x: 2, y: 1 };
function h() {
%MigrateInstance(c);
return 2;
}
%NeverOptimizeFunction(h);
function f() {
for (var i = 0; i < 100000; i++) {
var n = c.x + h();
assertEquals(4, n);
}
var o2 = [{ x: 2.5, y:1 }];
return o2;
}
f();
// Copyright 2013 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 c = { x: 2, y: 1 };
function g() {
var outer = { foo: 1 };
function f() {
var n = outer.foo;
for (var i = 0; i < 100000; i++) {
n += c.x + outer.foo;
}
var o2 = [{ x: 1.5, y: 1 }];
return o2;
}
return f;
}
var fun = g();
fun();
assertOptimized(fun);
fun();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment