Fix parallel recompilation wrt transition maps dependency.
R=ulan@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/15896038 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15032 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
dbb16eaec3
commit
b0afb77731
@ -88,11 +88,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
||||
}
|
||||
PopulateDeoptimizationData(code);
|
||||
info()->CommitDependentMaps(code);
|
||||
|
||||
for (int i = 0 ; i < transition_maps_.length(); i++) {
|
||||
transition_maps_.at(i)->AddDependentCode(
|
||||
DependentCode::kTransitionGroup, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4276,9 +4271,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
||||
}
|
||||
|
||||
if (!transition.is_null()) {
|
||||
if (transition->CanBeDeprecated()) {
|
||||
transition_maps_.Add(transition, info()->zone());
|
||||
}
|
||||
__ mov(scratch, Operand(transition));
|
||||
__ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
|
||||
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
|
||||
|
@ -56,7 +56,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
deoptimizations_(4, info->zone()),
|
||||
deopt_jump_table_(4, info->zone()),
|
||||
deoptimization_literals_(8, info->zone()),
|
||||
transition_maps_(0, info->zone()),
|
||||
inlined_function_count_(0),
|
||||
scope_(info->scope()),
|
||||
status_(UNUSED),
|
||||
@ -409,7 +408,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
ZoneList<LEnvironment*> deoptimizations_;
|
||||
ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
|
||||
ZoneList<Handle<Object> > deoptimization_literals_;
|
||||
ZoneList<Handle<Map> > transition_maps_;
|
||||
int inlined_function_count_;
|
||||
Scope* const scope_;
|
||||
Status status_;
|
||||
|
@ -5689,6 +5689,7 @@ class HStoreNamedField: public HTemplateInstruction<2> {
|
||||
= Representation::Tagged())
|
||||
: access_(access),
|
||||
field_representation_(field_representation),
|
||||
transition_(),
|
||||
transition_unique_id_(),
|
||||
new_space_dominator_(NULL) {
|
||||
SetOperandAt(0, obj);
|
||||
@ -5720,7 +5721,13 @@ class HStoreNamedField: public HTemplateInstruction<2> {
|
||||
HObjectAccess access() const { return access_; }
|
||||
Handle<Map> transition() const { return transition_; }
|
||||
UniqueValueId transition_unique_id() const { return transition_unique_id_; }
|
||||
void set_transition(Handle<Map> map) { transition_ = map; }
|
||||
void SetTransition(Handle<Map> map, CompilationInfo* info) {
|
||||
ASSERT(transition_.is_null()); // Only set once.
|
||||
if (map->CanBeDeprecated()) {
|
||||
map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info);
|
||||
}
|
||||
transition_ = map;
|
||||
}
|
||||
HValue* new_space_dominator() const { return new_space_dominator_; }
|
||||
|
||||
bool NeedsWriteBarrier() {
|
||||
|
@ -6253,7 +6253,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
|
||||
|
||||
if (transition_to_field) {
|
||||
Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
|
||||
instr->set_transition(transition);
|
||||
instr->SetTransition(transition, top_info());
|
||||
// TODO(fschneider): Record the new map type of the object in the IR to
|
||||
// enable elimination of redundant checks after the transition store.
|
||||
instr->SetGVNFlag(kChangesMaps);
|
||||
|
@ -110,11 +110,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
||||
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
|
||||
}
|
||||
info()->CommitDependentMaps(code);
|
||||
|
||||
for (int i = 0 ; i < transition_maps_.length(); i++) {
|
||||
transition_maps_.at(i)->AddDependentCode(
|
||||
DependentCode::kTransitionGroup, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4302,9 +4297,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
||||
}
|
||||
|
||||
if (!transition.is_null()) {
|
||||
if (transition->CanBeDeprecated()) {
|
||||
transition_maps_.Add(transition, info()->zone());
|
||||
}
|
||||
if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
|
||||
__ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
|
||||
} else {
|
||||
|
@ -58,7 +58,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
deoptimizations_(4, info->zone()),
|
||||
jump_table_(4, info->zone()),
|
||||
deoptimization_literals_(8, info->zone()),
|
||||
transition_maps_(0, info->zone()),
|
||||
inlined_function_count_(0),
|
||||
scope_(info->scope()),
|
||||
status_(UNUSED),
|
||||
@ -408,7 +407,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
ZoneList<LEnvironment*> deoptimizations_;
|
||||
ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
|
||||
ZoneList<Handle<Object> > deoptimization_literals_;
|
||||
ZoneList<Handle<Map> > transition_maps_;
|
||||
int inlined_function_count_;
|
||||
Scope* const scope_;
|
||||
Status status_;
|
||||
|
@ -88,11 +88,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
||||
}
|
||||
PopulateDeoptimizationData(code);
|
||||
info()->CommitDependentMaps(code);
|
||||
|
||||
for (int i = 0 ; i < transition_maps_.length(); i++) {
|
||||
transition_maps_.at(i)->AddDependentCode(
|
||||
DependentCode::kTransitionGroup, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3966,9 +3961,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
||||
}
|
||||
|
||||
if (!transition.is_null()) {
|
||||
if (transition->CanBeDeprecated()) {
|
||||
transition_maps_.Add(transition, info()->zone());
|
||||
}
|
||||
__ li(scratch, Operand(transition));
|
||||
__ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
|
||||
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
|
||||
|
@ -55,7 +55,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
deoptimizations_(4, info->zone()),
|
||||
deopt_jump_table_(4, info->zone()),
|
||||
deoptimization_literals_(8, info->zone()),
|
||||
transition_maps_(0, info->zone()),
|
||||
inlined_function_count_(0),
|
||||
scope_(info->scope()),
|
||||
status_(UNUSED),
|
||||
@ -411,7 +410,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
ZoneList<LEnvironment*> deoptimizations_;
|
||||
ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
|
||||
ZoneList<Handle<Object> > deoptimization_literals_;
|
||||
ZoneList<Handle<Map> > transition_maps_;
|
||||
int inlined_function_count_;
|
||||
Scope* const scope_;
|
||||
Status status_;
|
||||
|
@ -93,11 +93,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
||||
}
|
||||
PopulateDeoptimizationData(code);
|
||||
info()->CommitDependentMaps(code);
|
||||
|
||||
for (int i = 0 ; i < transition_maps_.length(); i++) {
|
||||
transition_maps_.at(i)->AddDependentCode(
|
||||
DependentCode::kTransitionGroup, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3995,9 +3990,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
||||
}
|
||||
|
||||
if (!transition.is_null()) {
|
||||
if (transition->CanBeDeprecated()) {
|
||||
transition_maps_.Add(transition, info()->zone());
|
||||
}
|
||||
if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
|
||||
__ Move(FieldOperand(object, HeapObject::kMapOffset), transition);
|
||||
} else {
|
||||
|
@ -57,7 +57,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
deoptimizations_(4, info->zone()),
|
||||
jump_table_(4, info->zone()),
|
||||
deoptimization_literals_(8, info->zone()),
|
||||
transition_maps_(0, info->zone()),
|
||||
inlined_function_count_(0),
|
||||
scope_(info->scope()),
|
||||
status_(UNUSED),
|
||||
@ -361,7 +360,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
ZoneList<LEnvironment*> deoptimizations_;
|
||||
ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
|
||||
ZoneList<Handle<Object> > deoptimization_literals_;
|
||||
ZoneList<Handle<Map> > transition_maps_;
|
||||
int inlined_function_count_;
|
||||
Scope* const scope_;
|
||||
Status status_;
|
||||
|
56
test/mjsunit/parallel-invalidate-transition-map.js
Normal file
56
test/mjsunit/parallel-invalidate-transition-map.js
Normal file
@ -0,0 +1,56 @@
|
||||
// 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: --track-fields --track-double-fields --allow-natives-syntax
|
||||
// Flags: --parallel-recompilation --parallel-recompilation-delay=50
|
||||
|
||||
function assertUnoptimized(fun) {
|
||||
assertTrue(%GetOptimizationStatus(fun) != 1);
|
||||
}
|
||||
|
||||
function new_object() {
|
||||
var o = {};
|
||||
o.a = 1;
|
||||
o.b = 2;
|
||||
return o;
|
||||
}
|
||||
|
||||
function add_field(obj) {
|
||||
obj.c = 3;
|
||||
}
|
||||
|
||||
add_field(new_object());
|
||||
add_field(new_object());
|
||||
%OptimizeFunctionOnNextCall(add_field, "parallel");
|
||||
|
||||
var o = new_object();
|
||||
add_field(o); // Trigger optimization.
|
||||
assertUnoptimized(add_field); // Not yet optimized.
|
||||
o.c = 2.2; // Invalidate transition map.
|
||||
%CompleteOptimization(add_field); // Conclude optimization with...
|
||||
assertUnoptimized(add_field); // ... bailing out due to map dependency.
|
||||
|
Loading…
Reference in New Issue
Block a user