Revision: 15005
Author: yang...@chromium.org
Date: Fri Jun 7 06:27:03 2013
Log: Enable map dependency to in-flight compilation info.
R=u...@chromium.org
BUG=
Review URL: https://chromiumcodereview.appspot.com/16542003
http://code.google.com/p/v8/source/detail?r=15005
Modified:
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.h
/branches/bleeding_edge/src/compiler.cc
/branches/bleeding_edge/src/compiler.h
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/mips/lithium-codegen-mips.h
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.h
/branches/bleeding_edge/test/mjsunit/compiler/parallel-proto-change.js
/branches/bleeding_edge/test/mjsunit/manual-parallel-recompile.js
/branches/bleeding_edge/test/mjsunit/parallel-optimize-disabled.js
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jun 4
05:48:51 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Jun 7
06:27:03 2013
@@ -87,10 +87,8 @@
RegisterDependentCodeForEmbeddedMaps(code);
}
PopulateDeoptimizationData(code);
- for (int i = 0 ; i < prototype_maps_.length(); i++) {
- prototype_maps_.at(i)->AddDependentCode(
- DependentCode::kPrototypeCheckGroup, code);
- }
+ info()->CommitDependentMaps(code);
+
for (int i = 0 ; i < transition_maps_.length(); i++) {
transition_maps_.at(i)->AddDependentCode(
DependentCode::kTransitionGroup, code);
@@ -5399,11 +5397,7 @@
ASSERT(prototypes->length() == maps->length());
- if (instr->hydrogen()->CanOmitPrototypeChecks()) {
- for (int i = 0; i < maps->length(); i++) {
- prototype_maps_.Add(maps->at(i), info()->zone());
- }
- } else {
+ if (!instr->hydrogen()->CanOmitPrototypeChecks()) {
for (int i = 0; i < prototypes->length(); i++) {
__ LoadHeapObject(prototype_reg, prototypes->at(i));
__ ldr(map_reg, FieldMemOperand(prototype_reg,
HeapObject::kMapOffset));
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Tue Jun 4
01:28:33 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Fri Jun 7
06:27:03 2013
@@ -56,7 +56,6 @@
deoptimizations_(4, info->zone()),
deopt_jump_table_(4, info->zone()),
deoptimization_literals_(8, info->zone()),
- prototype_maps_(0, info->zone()),
transition_maps_(0, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
@@ -410,7 +409,6 @@
ZoneList<LEnvironment*> deoptimizations_;
ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
ZoneList<Handle<Object> > deoptimization_literals_;
- ZoneList<Handle<Map> > prototype_maps_;
ZoneList<Handle<Map> > transition_maps_;
int inlined_function_count_;
Scope* const scope_;
=======================================
--- /branches/bleeding_edge/src/compiler.cc Thu Jun 6 08:32:39 2013
+++ /branches/bleeding_edge/src/compiler.cc Fri Jun 7 06:27:03 2013
@@ -106,6 +106,9 @@
opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
? new List<OffsetRange>(2) : NULL;
+ for (int i = 0; i < DependentCode::kGroupCount; i++) {
+ dependent_maps_[i] = NULL;
+ }
if (mode == STUB) {
mode_ = STUB;
return;
@@ -125,6 +128,41 @@
CompilationInfo::~CompilationInfo() {
delete deferred_handles_;
delete no_frame_ranges_;
+#ifdef DEBUG
+ // Check that no dependent maps have been added or added dependent maps
have
+ // been rolled back or committed.
+ for (int i = 0; i < DependentCode::kGroupCount; i++) {
+ ASSERT_EQ(NULL, dependent_maps_[i]);
+ }
+#endif // DEBUG
+}
+
+
+void CompilationInfo::CommitDependentMaps(Handle<Code> code) {
+ for (int i = 0; i < DependentCode::kGroupCount; i++) {
+ ZoneList<Handle<Map> >* group_maps = dependent_maps_[i];
+ if (group_maps == NULL) continue;
+ ASSERT(!object_wrapper_.is_null());
+ for (int j = 0; j < group_maps->length(); j++) {
+ group_maps->at(j)->dependent_code()->UpdateToFinishedCode(
+ static_cast<DependentCode::DependencyGroup>(i), this, *code);
+ }
+ dependent_maps_[i] = NULL; // Zone-allocated, no need to delete.
+ }
+}
+
+
+void CompilationInfo::RollbackDependentMaps() {
+ // Unregister from all dependent maps if not yet committed.
+ for (int i = 0; i < DependentCode::kGroupCount; i++) {
+ ZoneList<Handle<Map> >* group_maps = dependent_maps_[i];
+ if (group_maps == NULL) continue;
+ for (int j = 0; j < group_maps->length(); j++) {
+ group_maps->at(j)->dependent_code()->RemoveCompilationInfo(
+ static_cast<DependentCode::DependencyGroup>(i), this);
+ }
+ dependent_maps_[i] = NULL; // Zone-allocated, no need to delete.
+ }
}
@@ -982,7 +1020,7 @@
// The function may have already been optimized by OSR. Simply continue.
// Except when OSR already disabled optimization for some reason.
if (info->shared_info()->optimization_disabled()) {
- info->SetCode(Handle<Code>(info->shared_info()->code()));
+ info->AbortOptimization();
InstallFullCode(*info);
if (FLAG_trace_parallel_recompilation) {
PrintF(" ** aborting optimization for ");
@@ -1000,9 +1038,11 @@
// If crankshaft succeeded, install the optimized code else install
// the unoptimized code.
OptimizingCompiler::Status status = optimizing_compiler->last_status();
- if (status != OptimizingCompiler::SUCCEEDED) {
- optimizing_compiler->info()->set_bailout_reason(
- "failed/bailed out last time");
+ if (info->HasAbortedDueToDependentMap()) {
+ info->set_bailout_reason("bailed out due to dependent map");
+ status = optimizing_compiler->AbortOptimization();
+ } else if (status != OptimizingCompiler::SUCCEEDED) {
+ info->set_bailout_reason("failed/bailed out last time");
status = optimizing_compiler->AbortOptimization();
} else {
status = optimizing_compiler->GenerateAndInstallCode();
=======================================
--- /branches/bleeding_edge/src/compiler.h Mon May 27 06:59:20 2013
+++ /branches/bleeding_edge/src/compiler.h Fri Jun 7 06:27:03 2013
@@ -57,12 +57,8 @@
// is constructed based on the resources available at compile-time.
class CompilationInfo {
public:
- CompilationInfo(Handle<Script> script, Zone* zone);
- CompilationInfo(Handle<SharedFunctionInfo> shared_info, Zone* zone);
CompilationInfo(Handle<JSFunction> closure, Zone* zone);
- CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, Zone* zone);
-
- ~CompilationInfo();
+ virtual ~CompilationInfo();
Isolate* isolate() {
ASSERT(Isolate::Current() == isolate_);
@@ -243,6 +239,17 @@
deferred_handles_ = deferred_handles;
}
+ ZoneList<Handle<Map> >* dependent_maps(DependentCode::DependencyGroup
group) {
+ if (dependent_maps_[group] == NULL) {
+ dependent_maps_[group] = new(zone_) ZoneList<Handle<Map> >(2, zone_);
+ }
+ return dependent_maps_[group];
+ }
+
+ void CommitDependentMaps(Handle<Code> code);
+
+ void RollbackDependentMaps();
+
void SaveHandles() {
SaveHandle(&closure_);
SaveHandle(&shared_info_);
@@ -276,6 +283,26 @@
return result;
}
+ Handle<Foreign> object_wrapper() {
+ if (object_wrapper_.is_null()) {
+ object_wrapper_ =
+
isolate()->factory()->NewForeign(reinterpret_cast<Address>(this));
+ }
+ return object_wrapper_;
+ }
+
+ void AbortDueToDependentMap() {
+ mode_ = DEPENDENT_MAP_ABORT;
+ }
+
+ bool HasAbortedDueToDependentMap() {
+ return mode_ == DEPENDENT_MAP_ABORT;
+ }
+
+ protected:
+ CompilationInfo(Handle<Script> script, Zone* zone);
+ CompilationInfo(Handle<SharedFunctionInfo> shared_info, Zone* zone);
+ CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, Zone* zone);
private:
Isolate* isolate_;
@@ -289,7 +316,8 @@
BASE,
OPTIMIZE,
NONOPT,
- STUB
+ STUB,
+ DEPENDENT_MAP_ABORT
};
void Initialize(Isolate* isolate, Mode mode, Zone* zone);
@@ -369,6 +397,8 @@
DeferredHandles* deferred_handles_;
+ ZoneList<Handle<Map> >* dependent_maps_[DependentCode::kGroupCount];
+
template<typename T>
void SaveHandle(Handle<T> *object) {
if (!object->is_null()) {
@@ -387,6 +417,8 @@
// during graph optimization.
int opt_count_;
+ Handle<Foreign> object_wrapper_;
+
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};
@@ -407,10 +439,17 @@
: CompilationInfo(closure, &zone_),
zone_(closure->GetIsolate()),
zone_scope_(&zone_, DELETE_ON_EXIT) {}
- explicit CompilationInfoWithZone(HydrogenCodeStub* stub, Isolate*
isolate)
+ CompilationInfoWithZone(HydrogenCodeStub* stub, Isolate* isolate)
: CompilationInfo(stub, isolate, &zone_),
zone_(isolate),
zone_scope_(&zone_, DELETE_ON_EXIT) {}
+
+ // 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() {
+ RollbackDependentMaps();
+ }
private:
Zone zone_;
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Jun 7 04:00:39
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Jun 7 06:27:03
2013
@@ -2966,21 +2966,33 @@
public:
HCheckPrototypeMaps(Handle<JSObject> prototype,
Handle<JSObject> holder,
- Zone* zone)
+ Zone* zone,
+ CompilationInfo* info)
: prototypes_(2, zone),
maps_(2, zone),
first_prototype_unique_id_(),
- last_prototype_unique_id_() {
+ last_prototype_unique_id_(),
+ can_omit_prototype_maps_(true) {
SetFlag(kUseGVN);
SetGVNFlag(kDependsOnMaps);
// Keep a list of all objects on the prototype chain up to the holder
// and the expected maps.
while (true) {
prototypes_.Add(prototype, zone);
- maps_.Add(Handle<Map>(prototype->map()), zone);
+ Handle<Map> map(prototype->map());
+ maps_.Add(map, zone);
+ can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks();
if (prototype.is_identical_to(holder)) break;
prototype =
Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
}
+ if (can_omit_prototype_maps_) {
+ // Mark in-flight compilation as dependent on those maps.
+ for (int i = 0; i < maps()->length(); i++) {
+ Handle<Map> map = maps()->at(i);
+
map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
+ info);
+ }
+ }
}
ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
@@ -3005,12 +3017,7 @@
last_prototype_unique_id_ = UniqueValueId(prototypes_.last());
}
- bool CanOmitPrototypeChecks() {
- for (int i = 0; i < maps()->length(); i++) {
- if (!maps()->at(i)->CanOmitPrototypeChecks()) return false;
- }
- return true;
- }
+ bool CanOmitPrototypeChecks() { return can_omit_prototype_maps_; }
protected:
virtual bool DataEquals(HValue* other) {
@@ -3024,6 +3031,7 @@
ZoneList<Handle<Map> > maps_;
UniqueValueId first_prototype_unique_id_;
UniqueValueId last_prototype_unique_id_;
+ bool can_omit_prototype_maps_;
};
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Fri Jun 7 06:21:20 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Fri Jun 7 06:27:03 2013
@@ -3811,7 +3811,7 @@
void HOptimizedGraphBuilder::Bailout(const char* reason) {
- info()->set_bailout_reason(reason);
+ current_info()->set_bailout_reason(reason);
SetStackOverflow();
}
@@ -3868,11 +3868,11 @@
bool HOptimizedGraphBuilder::BuildGraph() {
- if (info()->function()->is_generator()) {
+ if (current_info()->function()->is_generator()) {
Bailout("function is a generator");
return false;
}
- Scope* scope = info()->scope();
+ Scope* scope = current_info()->scope();
if (scope->HasIllegalRedeclaration()) {
Bailout("function with illegal redeclaration");
return false;
@@ -3916,7 +3916,7 @@
AddInstruction(
new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry));
- VisitStatements(info()->function()->body());
+ VisitStatements(current_info()->function()->body());
if (HasStackOverflow()) return false;
if (current_block() != NULL) {
@@ -3928,7 +3928,7 @@
// last time this function was compiled, then this recompile is likely
not
// due to missing/inadequate type feedback, but rather too aggressive
// optimization. Disable optimistic LICM in that case.
- Handle<Code> unoptimized_code(info()->shared_info()->code());
+ Handle<Code> unoptimized_code(current_info()->shared_info()->code());
ASSERT(unoptimized_code->kind() == Code::FUNCTION);
Handle<TypeFeedbackInfo> type_info(
TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info()));
@@ -5117,7 +5117,7 @@
bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) {
- return statement->OsrEntryId() == info()->osr_ast_id();
+ return statement->OsrEntryId() == current_info()->osr_ast_id();
}
@@ -5504,9 +5504,9 @@
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
Handle<SharedFunctionInfo> shared_info =
- SearchSharedFunctionInfo(info()->shared_info()->code(), expr);
+ SearchSharedFunctionInfo(current_info()->shared_info()->code(),
expr);
if (shared_info.is_null()) {
- shared_info = Compiler::BuildFunctionInfo(expr, info()->script());
+ shared_info = Compiler::BuildFunctionInfo(expr,
current_info()->script());
}
// We also have a stack overflow if the recursive compilation did.
if (HasStackOverflow()) return;
@@ -5567,10 +5567,10 @@
HOptimizedGraphBuilder::GlobalPropertyAccess
HOptimizedGraphBuilder::LookupGlobalProperty(
Variable* var, LookupResult* lookup, bool is_store) {
- if (var->is_this() || !info()->has_global_object()) {
+ if (var->is_this() || !current_info()->has_global_object()) {
return kUseGeneric;
}
- Handle<GlobalObject> global(info()->global_object());
+ Handle<GlobalObject> global(current_info()->global_object());
global->Lookup(*var->name(), lookup);
if (!lookup->IsNormal() ||
(is_store && lookup->IsReadOnly()) ||
@@ -5585,7 +5585,7 @@
HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
ASSERT(var->IsContextSlot());
HValue* context = environment()->LookupContext();
- int length = info()->scope()->ContextChainLength(var->scope());
+ int length = current_info()->scope()->ContextChainLength(var->scope());
while (length-- > 0) {
HInstruction* context_instruction = new(zone()) HOuterContext(context);
AddInstruction(context_instruction);
@@ -5621,12 +5621,12 @@
LookupGlobalProperty(variable, &lookup, false);
if (type == kUseCell &&
- info()->global_object()->IsAccessCheckNeeded()) {
+ current_info()->global_object()->IsAccessCheckNeeded()) {
type = kUseGeneric;
}
if (type == kUseCell) {
- Handle<GlobalObject> global(info()->global_object());
+ Handle<GlobalObject> global(current_info()->global_object());
Handle<JSGlobalPropertyCell>
cell(global->GetPropertyCell(&lookup));
HLoadGlobalCell* instr =
new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
@@ -6217,7 +6217,8 @@
AddInstruction(new(zone()) HCheckPrototypeMaps(
Handle<JSObject>(JSObject::cast(map->prototype())),
Handle<JSObject>(JSObject::cast(proto)),
- zone()));
+ zone(),
+ top_info()));
}
HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
@@ -6556,7 +6557,7 @@
LookupResult lookup(isolate());
GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
if (type == kUseCell) {
- Handle<GlobalObject> global(info()->global_object());
+ Handle<GlobalObject> global(current_info()->global_object());
Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
HInstruction* instr =
new(zone()) HStoreGlobalCell(value, cell,
lookup.GetPropertyDetails());
@@ -6621,13 +6622,13 @@
// Bail out if we try to mutate a parameter value in a function
// using the arguments object. We do not (yet) correctly handle
the
// arguments property of the function.
- if (info()->scope()->arguments() != NULL) {
+ if (current_info()->scope()->arguments() != NULL) {
// Parameters will be allocated to context slots. We have no
// direct way to detect that the variable is a parameter so we do
// a linear search of the parameter variables.
- int count = info()->scope()->num_parameters();
+ int count = current_info()->scope()->num_parameters();
for (int i = 0; i < count; ++i) {
- if (var == info()->scope()->parameter(i)) {
+ if (var == current_info()->scope()->parameter(i)) {
Bailout(
"assignment to parameter, function uses arguments
object");
}
@@ -6847,12 +6848,12 @@
// Bail out if we try to mutate a parameter value in a function
using
// the arguments object. We do not (yet) correctly handle the
// arguments property of the function.
- if (info()->scope()->arguments() != NULL) {
+ if (current_info()->scope()->arguments() != NULL) {
// Parameters will rewrite to context slots. We have no direct
way
// to detect that the variable is a parameter.
- int count = info()->scope()->num_parameters();
+ int count = current_info()->scope()->num_parameters();
for (int i = 0; i < count; ++i) {
- if (var == info()->scope()->parameter(i)) {
+ if (var == current_info()->scope()->parameter(i)) {
return Bailout("assignment to parameter in arguments
object");
}
}
@@ -7014,8 +7015,8 @@
Handle<JSObject> holder(lookup.holder());
Handle<Map> holder_map(holder->map());
AddCheckMap(object, map);
- AddInstruction(
- new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
+ AddInstruction(new(zone()) HCheckPrototypeMaps(
+ prototype, holder, zone(), top_info()));
HValue* holder_value = AddInstruction(new(zone())
HConstant(holder, Representation::Tagged()));
return BuildLoadNamedField(holder_value,
@@ -7029,7 +7030,8 @@
Handle<JSObject> holder(lookup.holder());
Handle<Map> holder_map(holder->map());
AddCheckMap(object, map);
- AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder,
zone()));
+ AddInstruction(new(zone()) HCheckPrototypeMaps(
+ prototype, holder, zone(), top_info()));
Handle<JSFunction>
function(lookup.GetConstantFunctionFromMap(*holder_map));
return new(zone()) HConstant(function, Representation::Tagged());
}
@@ -7066,8 +7068,8 @@
isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
Handle<JSObject> prototype(JSObject::cast(map->prototype()),
isolate());
Handle<JSObject> object_prototype =
isolate()->initial_object_prototype();
- AddInstruction(
- new(zone()) HCheckPrototypeMaps(prototype, object_prototype,
zone()));
+ AddInstruction(new(zone()) HCheckPrototypeMaps(
+ prototype, object_prototype, zone(), top_info()));
load_mode = ALLOW_RETURN_HOLE;
graph()->MarkDependsOnEmptyArrayProtoElements();
}
@@ -7582,8 +7584,8 @@
Handle<Map>
receiver_map) {
if (!holder.is_null()) {
Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
- AddInstruction(
- new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
+ AddInstruction(new(zone()) HCheckPrototypeMaps(
+ prototype, holder, zone(), top_info()));
}
}
@@ -7728,7 +7730,7 @@
expr->ComputeTarget(map, name);
AddCheckPrototypeMaps(expr->holder(), map);
if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
- Handle<JSFunction> caller = info()->closure();
+ Handle<JSFunction> caller = current_info()->closure();
SmartArrayPointer<char> caller_name =
caller->shared()->DebugName()->ToCString();
PrintF("Trying to inline the polymorphic call to %s from %s\n",
@@ -7812,7 +7814,7 @@
// Precondition: call is monomorphic and we have found a target with the
// appropriate arity.
- Handle<JSFunction> caller = info()->closure();
+ Handle<JSFunction> caller = current_info()->closure();
Handle<SharedFunctionInfo> target_shared(target->shared());
// Do a quick check on source code length to avoid parsing large
@@ -7848,7 +7850,7 @@
int nodes_added = InliningAstSize(target);
if (nodes_added == kNotInlinable) return false;
- Handle<JSFunction> caller = info()->closure();
+ Handle<JSFunction> caller = current_info()->closure();
if (nodes_added > Min(FLAG_max_inlined_nodes,
kUnlimitedMaxInlinedNodes)) {
TraceInline(target, caller, "target AST is too large [early]");
@@ -7857,7 +7859,7 @@
#if !defined(V8_TARGET_ARCH_IA32)
// Target must be able to use caller's context.
- CompilationInfo* outer_info = info();
+ CompilationInfo* outer_info = current_info();
if (target->context() != outer_info->closure()->context() ||
outer_info->scope()->contains_with() ||
outer_info->scope()->num_heap_slots() > 0) {
@@ -8292,7 +8294,8 @@
Call::GetPrototypeForPrimitiveCheck(STRING_CHECK,
expr->holder()->GetIsolate()),
expr->holder(),
- zone()));
+ zone(),
+ top_info()));
HInstruction* char_code =
BuildStringCharCodeAt(context, string, index);
if (id == kStringCharCodeAt) {
@@ -8443,7 +8446,7 @@
return false;
}
- if (info()->scope()->arguments() == NULL) return false;
+ if (current_info()->scope()->arguments() == NULL) return false;
ZoneList<Expression*>* args = expr->arguments();
if (args->length() != 2) return false;
@@ -8684,8 +8687,8 @@
LookupResult lookup(isolate());
GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup,
false);
if (type == kUseCell &&
- !info()->global_object()->IsAccessCheckNeeded()) {
- Handle<GlobalObject> global(info()->global_object());
+ !current_info()->global_object()->IsAccessCheckNeeded()) {
+ Handle<GlobalObject> global(current_info()->global_object());
known_global_function = expr->ComputeGlobalTarget(global, &lookup);
}
if (known_global_function) {
@@ -8720,7 +8723,7 @@
}
if (TryInlineCall(expr)) return;
- if (expr->target().is_identical_to(info()->closure())) {
+ if (expr->target().is_identical_to(current_info()->closure())) {
graph()->MarkRecursive();
}
@@ -9219,13 +9222,13 @@
// Bail out if we try to mutate a parameter value in a function
// using the arguments object. We do not (yet) correctly handle
the
// arguments property of the function.
- if (info()->scope()->arguments() != NULL) {
+ if (current_info()->scope()->arguments() != NULL) {
// Parameters will rewrite to context slots. We have no direct
// way to detect that the variable is a parameter so we use a
// linear search of the parameter list.
- int count = info()->scope()->num_parameters();
+ int count = current_info()->scope()->num_parameters();
for (int i = 0; i < count; ++i) {
- if (var == info()->scope()->parameter(i)) {
+ if (var == current_info()->scope()->parameter(i)) {
return Bailout("assignment to parameter in arguments
object");
}
}
@@ -9824,10 +9827,10 @@
VariableProxy* proxy = expr->right()->AsVariableProxy();
bool global_function = (proxy != NULL) &&
proxy->var()->IsUnallocated();
if (global_function &&
- info()->has_global_object() &&
- !info()->global_object()->IsAccessCheckNeeded()) {
+ current_info()->has_global_object() &&
+ !current_info()->global_object()->IsAccessCheckNeeded()) {
Handle<String> name = proxy->name();
- Handle<GlobalObject> global(info()->global_object());
+ Handle<GlobalObject> global(current_info()->global_object());
LookupResult lookup(isolate());
global->Lookup(*name, &lookup);
if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) {
@@ -10267,9 +10270,9 @@
Handle<FixedArray> array =
isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
for (int i = 0; i < globals_.length(); ++i) array->set(i,
*globals_.at(i));
- int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
- DeclareGlobalsNativeFlag::encode(info()->is_native()) |
-
DeclareGlobalsLanguageMode::encode(info()->language_mode());
+ int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
+ DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
+
DeclareGlobalsLanguageMode::encode(current_info()->language_mode());
HInstruction* result = new(zone()) HDeclareGlobals(
environment()->LookupContext(), array, flags);
AddInstruction(result);
@@ -10323,8 +10326,8 @@
switch (variable->location()) {
case Variable::UNALLOCATED: {
globals_.Add(variable->name(), zone());
- Handle<SharedFunctionInfo> function =
- Compiler::BuildFunctionInfo(declaration->fun(),
info()->script());
+ Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo(
+ declaration->fun(), current_info()->script());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_.Add(function, zone());
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Wed Jun 5 10:24:14 2013
+++ /branches/bleeding_edge/src/hydrogen.h Fri Jun 7 06:27:03 2013
@@ -968,6 +968,7 @@
Zone* zone() const { return info_->zone(); }
HGraph* graph() const { return graph_; }
Isolate* isolate() const { return graph_->isolate(); }
+ CompilationInfo* top_info() { return info_; }
HGraph* CreateGraph();
@@ -1489,7 +1490,7 @@
void set_ast_context(AstContext* context) { ast_context_ = context; }
// Accessors forwarded to the function state.
- CompilationInfo* info() const {
+ CompilationInfo* current_info() const {
return function_state()->compilation_info();
}
AstContext* call_context() const {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Jun 4
05:48:51 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Jun 7
06:27:03 2013
@@ -109,10 +109,8 @@
if (!info()->IsStub()) {
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
- for (int i = 0 ; i < prototype_maps_.length(); i++) {
- prototype_maps_.at(i)->AddDependentCode(
- DependentCode::kPrototypeCheckGroup, code);
- }
+ info()->CommitDependentMaps(code);
+
for (int i = 0 ; i < transition_maps_.length(); i++) {
transition_maps_.at(i)->AddDependentCode(
DependentCode::kTransitionGroup, code);
@@ -5988,11 +5986,7 @@
ASSERT(prototypes->length() == maps->length());
- if (instr->hydrogen()->CanOmitPrototypeChecks()) {
- for (int i = 0; i < maps->length(); i++) {
- prototype_maps_.Add(maps->at(i), info()->zone());
- }
- } else {
+ if (!instr->hydrogen()->CanOmitPrototypeChecks()) {
for (int i = 0; i < prototypes->length(); i++) {
__ LoadHeapObject(reg, prototypes->at(i));
DoCheckMapCommon(reg, maps->at(i), instr);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Tue Jun 4
01:28:33 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Fri Jun 7
06:27:03 2013
@@ -58,7 +58,6 @@
deoptimizations_(4, info->zone()),
jump_table_(4, info->zone()),
deoptimization_literals_(8, info->zone()),
- prototype_maps_(0, info->zone()),
transition_maps_(0, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
@@ -409,7 +408,6 @@
ZoneList<LEnvironment*> deoptimizations_;
ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
ZoneList<Handle<Object> > deoptimization_literals_;
- ZoneList<Handle<Map> > prototype_maps_;
ZoneList<Handle<Map> > transition_maps_;
int inlined_function_count_;
Scope* const scope_;
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Tue Jun 4 10:20:06 2013
+++ /branches/bleeding_edge/src/mark-compact.cc Fri Jun 7 06:27:03 2013
@@ -2481,11 +2481,12 @@
int number_of_entries = starts.number_of_entries();
if (number_of_entries == 0) return;
for (int i = 0; i < number_of_entries; i++) {
+ if (!entries->is_code_at(i)) continue;
Code* code = entries->code_at(i);
if (IsMarked(code) && !code->marked_for_deoptimization()) {
code->set_marked_for_deoptimization(true);
}
- entries->clear_code_at(i);
+ entries->clear_at(i);
}
map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
}
@@ -2502,14 +2503,15 @@
for (int g = 0; g < DependentCode::kGroupCount; g++) {
int group_number_of_entries = 0;
for (int i = starts.at(g); i < starts.at(g + 1); i++) {
+ if (!entries->is_code_at(i)) continue;
Code* code = entries->code_at(i);
if (IsMarked(code) && !code->marked_for_deoptimization()) {
if (new_number_of_entries + group_number_of_entries != i) {
- entries->set_code_at(new_number_of_entries +
- group_number_of_entries, code);
+ entries->set_object_at(
+ new_number_of_entries + group_number_of_entries, code);
}
- Object** slot = entries->code_slot_at(new_number_of_entries +
- group_number_of_entries);
+ Object** slot = entries->slot_at(new_number_of_entries +
+ group_number_of_entries);
RecordSlot(slot, slot, code);
group_number_of_entries++;
}
@@ -2520,7 +2522,7 @@
new_number_of_entries += group_number_of_entries;
}
for (int i = new_number_of_entries; i < number_of_entries; i++) {
- entries->clear_code_at(i);
+ entries->clear_at(i);
}
}
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Jun 4
13:17:22 2013
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Fri Jun 7
06:27:03 2013
@@ -87,10 +87,8 @@
RegisterDependentCodeForEmbeddedMaps(code);
}
PopulateDeoptimizationData(code);
- for (int i = 0 ; i < prototype_maps_.length(); i++) {
- prototype_maps_.at(i)->AddDependentCode(
- DependentCode::kPrototypeCheckGroup, code);
- }
+ info()->CommitDependentMaps(code);
+
for (int i = 0 ; i < transition_maps_.length(); i++) {
transition_maps_.at(i)->AddDependentCode(
DependentCode::kTransitionGroup, code);
@@ -5127,11 +5125,7 @@
ASSERT(prototypes->length() == maps->length());
- if (instr->hydrogen()->CanOmitPrototypeChecks()) {
- for (int i = 0; i < maps->length(); i++) {
- prototype_maps_.Add(maps->at(i), info()->zone());
- }
- } else {
+ if (!instr->hydrogen()->CanOmitPrototypeChecks()) {
for (int i = 0; i < prototypes->length(); i++) {
__ LoadHeapObject(prototype_reg, prototypes->at(i));
__ lw(map_reg, FieldMemOperand(prototype_reg,
HeapObject::kMapOffset));
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Tue Jun 4
01:28:33 2013
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Fri Jun 7
06:27:03 2013
@@ -55,7 +55,6 @@
deoptimizations_(4, info->zone()),
deopt_jump_table_(4, info->zone()),
deoptimization_literals_(8, info->zone()),
- prototype_maps_(0, info->zone()),
transition_maps_(0, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
@@ -412,7 +411,6 @@
ZoneList<LEnvironment*> deoptimizations_;
ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
ZoneList<Handle<Object> > deoptimization_literals_;
- ZoneList<Handle<Map> > prototype_maps_;
ZoneList<Handle<Map> > transition_maps_;
int inlined_function_count_;
Scope* const scope_;
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Fri Jun 7 03:52:11 2013
+++ /branches/bleeding_edge/src/objects-inl.h Fri Jun 7 06:27:03 2013
@@ -3657,17 +3657,6 @@
return !HasTransitionArray() && !is_dictionary_map() &&
FLAG_omit_prototype_checks_for_leaf_maps;
}
-
-
-void Map::AddDependentCode(DependentCode::DependencyGroup group,
- Handle<Code> code) {
- Handle<DependentCode> codes =
- DependentCode::Insert(Handle<DependentCode>(dependent_code()),
- group, code);
- if (*codes != dependent_code()) {
- set_dependent_code(*codes);
- }
-}
int DependentCode::number_of_entries(DependencyGroup group) {
@@ -3681,32 +3670,52 @@
}
+bool DependentCode::is_code_at(int i) {
+ return get(kCodesStartIndex + i)->IsCode();
+}
+
Code* DependentCode::code_at(int i) {
return Code::cast(get(kCodesStartIndex + i));
}
-void DependentCode::set_code_at(int i, Code* value) {
- set(kCodesStartIndex + i, value);
+CompilationInfo* DependentCode::compilation_info_at(int i) {
+ return reinterpret_cast<CompilationInfo*>(
+ Foreign::cast(get(kCodesStartIndex + i))->foreign_address());
+}
+
+
+void DependentCode::set_object_at(int i, Object* object) {
+ set(kCodesStartIndex + i, object);
+}
+
+
+Object* DependentCode::object_at(int i) {
+ return get(kCodesStartIndex + i);
}
-Object** DependentCode::code_slot_at(int i) {
+Object** DependentCode::slot_at(int i) {
return HeapObject::RawField(
this, FixedArray::OffsetOfElementAt(kCodesStartIndex + i));
}
-void DependentCode::clear_code_at(int i) {
+void DependentCode::clear_at(int i) {
set_undefined(kCodesStartIndex + i);
}
+
+
+void DependentCode::copy(int from, int to) {
+ set(kCodesStartIndex + to, get(kCodesStartIndex + from));
+}
void DependentCode::ExtendGroup(DependencyGroup group) {
GroupStartIndexes starts(this);
for (int g = kGroupCount - 1; g > group; g--) {
if (starts.at(g) < starts.at(g + 1)) {
- set_code_at(starts.at(g + 1), code_at(starts.at(g)));
+ copy(starts.at(g), starts.at(g + 1));
}
}
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Fri Jun 7 00:56:49 2013
+++ /branches/bleeding_edge/src/objects.cc Fri Jun 7 06:27:03 2013
@@ -11088,6 +11088,23 @@
GetHeap()->the_hole_value(),
proto_transitions->length());
}
+
+
+void Map::AddDependentCompilationInfo(DependentCode::DependencyGroup group,
+ CompilationInfo* info) {
+ Handle<DependentCode> codes = DependentCode::Insert(
+ Handle<DependentCode>(dependent_code()), group,
info->object_wrapper());
+ if (*codes != dependent_code()) set_dependent_code(*codes);
+ info->dependent_maps(group)->Add(Handle<Map>(this), info->zone());
+}
+
+
+void Map::AddDependentCode(DependentCode::DependencyGroup group,
+ Handle<Code> code) {
+ Handle<DependentCode> codes = DependentCode::Insert(
+ Handle<DependentCode>(dependent_code()), group, code);
+ if (*codes != dependent_code()) set_dependent_code(*codes);
+}
DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode*
entries) {
@@ -11106,13 +11123,13 @@
Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
DependencyGroup group,
- Handle<Code> value) {
+ Handle<Object> object) {
GroupStartIndexes starts(*entries);
int start = starts.at(group);
int end = starts.at(group + 1);
int number_of_entries = starts.number_of_entries();
- if (start < end && entries->code_at(end - 1) == *value) {
- // Do not append the code if it is already in the array.
+ if (start < end && entries->object_at(end - 1) == *object) {
+ // Do not append the compilation info if it is already in the array.
// It is sufficient to just check only the last element because
// we process embedded maps of an optimized code in one batch.
return entries;
@@ -11129,7 +11146,7 @@
end = starts.at(group + 1);
number_of_entries = starts.number_of_entries();
for (int i = 0; i < number_of_entries; i++) {
- entries->clear_code_at(i);
+ entries->clear_at(i);
}
// If the old fixed array was empty, we need to reset counters of the
// new array.
@@ -11141,17 +11158,78 @@
entries = new_entries;
}
entries->ExtendGroup(group);
- entries->set_code_at(end, *value);
+ entries->set_object_at(end, *object);
entries->set_number_of_entries(group, end + 1 - start);
return entries;
}
+
+
+void DependentCode::UpdateToFinishedCode(DependencyGroup group,
+ CompilationInfo* info,
+ Code* code) {
+ DisallowHeapAllocation no_gc;
+ AllowDeferredHandleDereference get_object_wrapper;
+ Foreign* info_wrapper = *info->object_wrapper();
+ GroupStartIndexes starts(this);
+ int start = starts.at(group);
+ int end = starts.at(group + 1);
+ for (int i = start; i < end; i++) {
+ if (object_at(i) == info_wrapper) {
+ set_object_at(i, code);
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ for (int i = start; i < end; i++) {
+ ASSERT(is_code_at(i) || compilation_info_at(i) != info);
+ }
+#endif
+}
+
+
+void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup
group,
+ CompilationInfo* info) {
+ DisallowHeapAllocation no_allocation;
+ AllowDeferredHandleDereference get_object_wrapper;
+ Foreign* info_wrapper = *info->object_wrapper();
+ GroupStartIndexes starts(this);
+ int start = starts.at(group);
+ int end = starts.at(group + 1);
+ // Find compilation info wrapper.
+ int info_pos = -1;
+ for (int i = start; i < end; i++) {
+ if (object_at(i) == info_wrapper) {
+ info_pos = i;
+ break;
+ }
+ }
+ if (info_pos == -1) return; // Not found.
+ int gap = info_pos;
+ // Use the last of each group to fill the gap in the previous group.
+ for (int i = group; i < kGroupCount; i++) {
+ int last_of_group = starts.at(group + 1) - 1;
+ ASSERT(last_of_group >= gap);
+ if (last_of_group == gap) continue;
+ copy(last_of_group, gap);
+ gap = last_of_group;
+ }
+ clear_at(gap); // Clear last gap.
+ set_number_of_entries(group, end - start - 1);
+
+#ifdef DEBUG
+ for (int i = start; i < end - 1; i++) {
+ ASSERT(is_code_at(i) || compilation_info_at(i) != info);
+ }
+#endif
+}
bool DependentCode::Contains(DependencyGroup group, Code* code) {
GroupStartIndexes starts(this);
- int number_of_entries = starts.at(kGroupCount);
+ int number_of_entries = starts.number_of_code_entries();
for (int i = 0; i < number_of_entries; i++) {
- if (code_at(i) == code) return true;
+ if (object_at(i) == code) return true;
}
return false;
}
@@ -11172,20 +11250,25 @@
DependentCode::GroupStartIndexes starts(this);
int start = starts.at(group);
int end = starts.at(group + 1);
- int number_of_entries = starts.at(DependentCode::kGroupCount);
+ int code_entries = starts.number_of_code_entries();
if (start == end) return;
for (int i = start; i < end; i++) {
- Code* code = code_at(i);
- code->set_marked_for_deoptimization(true);
+ if (is_code_at(i)) {
+ Code* code = code_at(i);
+ code->set_marked_for_deoptimization(true);
+ } else {
+ CompilationInfo* info = compilation_info_at(i);
+ info->AbortDueToDependentMap();
+ }
}
// Compact the array by moving all subsequent groups to fill in the new
holes.
- for (int src = end, dst = start; src < number_of_entries; src++, dst++) {
- set_code_at(dst, code_at(src));
+ for (int src = end, dst = start; src < code_entries; src++, dst++) {
+ copy(src, dst);
}
// Now the holes are at the end of the array, zap them for heap-verifier.
int removed = end - start;
- for (int i = number_of_entries - removed; i < number_of_entries; i++) {
- clear_code_at(i);
+ for (int i = code_entries - removed; i < code_entries; i++) {
+ clear_at(i);
}
set_number_of_entries(group, 0);
DeoptimizeDependentCodeFilter filter;
=======================================
--- /branches/bleeding_edge/src/objects.h Fri Jun 7 03:52:11 2013
+++ /branches/bleeding_edge/src/objects.h Fri Jun 7 06:27:03 2013
@@ -4980,6 +4980,8 @@
};
+class CompilationInfo;
+
// This class describes the layout of dependent codes array of a map. The
// array is partitioned into several groups of dependent codes. Each group
// contains codes with the same dependency on the map. The array has the
@@ -5027,14 +5029,23 @@
void Recompute(DependentCode* entries);
int at(int i) { return start_indexes_[i]; }
int number_of_entries() { return start_indexes_[kGroupCount]; }
+ int number_of_code_entries() {
+ return start_indexes_[kGroupCount];
+ }
private:
int start_indexes_[kGroupCount + 1];
};
bool Contains(DependencyGroup group, Code* code);
static Handle<DependentCode> Insert(Handle<DependentCode> entries,
- DependencyGroup group,
- Handle<Code> value);
+ DependencyGroup group,
+ Handle<Object> object);
+ void UpdateToFinishedCode(DependencyGroup group,
+ CompilationInfo* info,
+ Code* code);
+ void RemoveCompilationInfo(DependentCode::DependencyGroup group,
+ CompilationInfo* info);
+
void DeoptimizeDependentCodeGroup(Isolate* isolate,
DependentCode::DependencyGroup group);
@@ -5042,10 +5053,14 @@
// and the mark compact collector.
inline int number_of_entries(DependencyGroup group);
inline void set_number_of_entries(DependencyGroup group, int value);
+ inline bool is_code_at(int i);
inline Code* code_at(int i);
- inline void set_code_at(int i, Code* value);
- inline Object** code_slot_at(int i);
- inline void clear_code_at(int i);
+ inline CompilationInfo* compilation_info_at(int i);
+ inline void set_object_at(int i, Object* object);
+ inline Object** slot_at(int i);
+ inline Object* object_at(int i);
+ inline void clear_at(int i);
+ inline void copy(int from, int to);
static inline DependentCode* cast(Object* object);
private:
@@ -5554,8 +5569,11 @@
inline bool CanOmitPrototypeChecks();
- inline void AddDependentCode(DependentCode::DependencyGroup group,
- Handle<Code> code);
+ void AddDependentCompilationInfo(DependentCode::DependencyGroup group,
+ CompilationInfo* info);
+
+ void AddDependentCode(DependentCode::DependencyGroup group,
+ Handle<Code> code);
bool IsMapInArrayPrototypeChain();
=======================================
--- /branches/bleeding_edge/src/runtime.cc Fri Jun 7 03:52:11 2013
+++ /branches/bleeding_edge/src/runtime.cc Fri Jun 7 06:27:03 2013
@@ -8095,13 +8095,15 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WaitUntilOptimized) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CompleteOptimization) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- if (FLAG_parallel_recompilation) {
- if (V8::UseCrankshaft() && function->IsOptimizable()) {
- while (!function->IsOptimized()) OS::Sleep(50);
+ if (FLAG_parallel_recompilation && V8::UseCrankshaft()) {
+ // While function is in optimization pipeline, it is marked with
builtins.
+ while (function->code()->kind() == Code::BUILTIN) {
+ isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+ OS::Sleep(50);
}
}
return isolate->heap()->undefined_value();
=======================================
--- /branches/bleeding_edge/src/runtime.h Thu Jun 6 06:22:42 2013
+++ /branches/bleeding_edge/src/runtime.h Fri Jun 7 06:27:03 2013
@@ -96,7 +96,7 @@
F(ClearFunctionTypeFeedback, 1, 1) \
F(RunningInSimulator, 0, 1) \
F(OptimizeFunctionOnNextCall, -1, 1) \
- F(WaitUntilOptimized, 1, 1) \
+ F(CompleteOptimization, 1, 1) \
F(GetOptimizationStatus, 1, 1) \
F(GetOptimizationCount, 1, 1) \
F(CompileForOnStackReplacement, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Jun 4
05:48:51 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Jun 7
06:27:03 2013
@@ -92,10 +92,8 @@
RegisterDependentCodeForEmbeddedMaps(code);
}
PopulateDeoptimizationData(code);
- for (int i = 0 ; i < prototype_maps_.length(); i++) {
- prototype_maps_.at(i)->AddDependentCode(
- DependentCode::kPrototypeCheckGroup, code);
- }
+ info()->CommitDependentMaps(code);
+
for (int i = 0 ; i < transition_maps_.length(); i++) {
transition_maps_.at(i)->AddDependentCode(
DependentCode::kTransitionGroup, code);
@@ -5078,11 +5076,7 @@
ASSERT(prototypes->length() == maps->length());
- if (instr->hydrogen()->CanOmitPrototypeChecks()) {
- for (int i = 0; i < maps->length(); i++) {
- prototype_maps_.Add(maps->at(i), info()->zone());
- }
- } else {
+ if (!instr->hydrogen()->CanOmitPrototypeChecks()) {
for (int i = 0; i < prototypes->length(); i++) {
__ LoadHeapObject(reg, prototypes->at(i));
DoCheckMapCommon(reg, maps->at(i), instr);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Tue Jun 4
01:28:33 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Fri Jun 7
06:27:03 2013
@@ -57,7 +57,6 @@
deoptimizations_(4, info->zone()),
jump_table_(4, info->zone()),
deoptimization_literals_(8, info->zone()),
- prototype_maps_(0, info->zone()),
transition_maps_(0, info->zone()),
inlined_function_count_(0),
scope_(info->scope()),
@@ -362,7 +361,6 @@
ZoneList<LEnvironment*> deoptimizations_;
ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
ZoneList<Handle<Object> > deoptimization_literals_;
- ZoneList<Handle<Map> > prototype_maps_;
ZoneList<Handle<Map> > transition_maps_;
int inlined_function_count_;
Scope* const scope_;
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/parallel-proto-change.js
Tue Mar 12 11:03:18 2013
+++ /branches/bleeding_edge/test/mjsunit/compiler/parallel-proto-change.js
Fri Jun 7 06:27:03 2013
@@ -25,7 +25,12 @@
// (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 --parallel-recompilation
+// Flags: --allow-natives-syntax
+// Flags: --parallel-recompilation --parallel-recompilation-delay=50
+
+function assertUnoptimized(fun) {
+ assertTrue(%GetOptimizationStatus(fun) != 1);
+}
function f(foo) { return foo.bar(); }
@@ -36,10 +41,10 @@
assertEquals(1, f(o));
%OptimizeFunctionOnNextCall(f, "parallel");
-assertEquals(1, f(o));
-// Change the prototype chain during optimization.
+assertEquals(1, f(o)); // Trigger optimization.
+assertUnoptimized(f); // Optimization not yet done.
+// Change the prototype chain during optimization to trigger map
invalidation.
o.__proto__.__proto__ = { bar: function() { return 2; } };
-
-%WaitUntilOptimized(f);
-
+%CompleteOptimization(f); // Conclude optimization with...
+assertUnoptimized(f); // ... bailing out due to map dependency.
assertEquals(2, f(o));
=======================================
--- /branches/bleeding_edge/test/mjsunit/manual-parallel-recompile.js Tue
Mar 12 11:03:18 2013
+++ /branches/bleeding_edge/test/mjsunit/manual-parallel-recompile.js Fri
Jun 7 06:27:03 2013
@@ -25,11 +25,16 @@
// (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 --expose-gc --parallel-recompilation
+// Flags: --allow-natives-syntax --expose-gc
+// Flags: --parallel-recompilation --parallel-recompilation-delay=50
function assertUnoptimized(fun) {
assertTrue(%GetOptimizationStatus(fun) != 1);
}
+
+function assertOptimized(fun) {
+ assertTrue(%GetOptimizationStatus(fun) != 2);
+}
function f(x) {
var xx = x * x;
@@ -53,10 +58,13 @@
%OptimizeFunctionOnNextCall(f, "parallel");
%OptimizeFunctionOnNextCall(g, "parallel");
-f(g(2));
+f(g(2)); // Trigger optimization.
-assertUnoptimized(f);
+assertUnoptimized(f); // Not yet optimized.
assertUnoptimized(g);
-%WaitUntilOptimized(f);
-%WaitUntilOptimized(g);
+%CompleteOptimization(f); // Wait till optimized code is installed.
+%CompleteOptimization(g);
+
+assertOptimized(f); // Optimized now.
+assertOptimized(g);
=======================================
--- /branches/bleeding_edge/test/mjsunit/parallel-optimize-disabled.js Tue
Mar 12 11:03:18 2013
+++ /branches/bleeding_edge/test/mjsunit/parallel-optimize-disabled.js Fri
Jun 7 06:27:03 2013
@@ -43,4 +43,4 @@
%OptimizeFunctionOnNextCall(g, "parallel");
f(0); // g() is disabled for optimization on inlining attempt.
// Attempt to optimize g() should not run into any assertion.
-%WaitUntilOptimized(g);
+%CompleteOptimization(g);
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.