Commit 13724991 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Track global cells as special side effects in GVN.

R=mstarzinger@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19713 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1812f63f
......@@ -97,7 +97,8 @@ bool Handle<T>::IsDereferenceAllowed(DereferenceCheckMode mode) const {
if (!AllowHandleDereference::IsAllowed()) return false;
if (mode == INCLUDE_DEFERRED_CHECK &&
!AllowDeferredHandleDereference::IsAllowed()) {
// Accessing maps and internalized strings is safe.
// Accessing cells, maps and internalized strings is safe.
if (heap_object->IsCell()) return true;
if (heap_object->IsMap()) return true;
if (heap_object->IsInternalizedString()) return true;
return !heap->isolate()->IsDeferredHandle(handle);
......
......@@ -367,15 +367,28 @@ void HSideEffectMap::Store(SideEffects side_effects, HInstruction* instr) {
SideEffects SideEffectsTracker::ComputeChanges(HInstruction* instr) {
int index;
SideEffects result(instr->ChangesFlags());
if (result.ContainsFlag(kGlobalVars)) {
if (instr->IsStoreGlobalCell() &&
ComputeGlobalVar(HStoreGlobalCell::cast(instr)->cell(), &index)) {
result.RemoveFlag(kGlobalVars);
result.AddSpecial(GlobalVar(index));
} else {
for (index = 0; index < kNumberOfGlobalVars; ++index) {
result.AddSpecial(GlobalVar(index));
}
}
}
if (result.ContainsFlag(kInobjectFields)) {
int index;
if (instr->IsStoreNamedField() &&
ComputeInobjectField(HStoreNamedField::cast(instr)->access(), &index)) {
result.RemoveFlag(kInobjectFields);
result.AddSpecial(index);
result.AddSpecial(InobjectField(index));
} else {
result.AddAllSpecial();
for (index = 0; index < kNumberOfInobjectFields; ++index) {
result.AddSpecial(InobjectField(index));
}
}
}
return result;
......@@ -383,15 +396,28 @@ SideEffects SideEffectsTracker::ComputeChanges(HInstruction* instr) {
SideEffects SideEffectsTracker::ComputeDependsOn(HInstruction* instr) {
int index;
SideEffects result(instr->DependsOnFlags());
if (result.ContainsFlag(kGlobalVars)) {
if (instr->IsLoadGlobalCell() &&
ComputeGlobalVar(HLoadGlobalCell::cast(instr)->cell(), &index)) {
result.RemoveFlag(kGlobalVars);
result.AddSpecial(GlobalVar(index));
} else {
for (index = 0; index < kNumberOfGlobalVars; ++index) {
result.AddSpecial(GlobalVar(index));
}
}
}
if (result.ContainsFlag(kInobjectFields)) {
int index;
if (instr->IsLoadNamedField() &&
ComputeInobjectField(HLoadNamedField::cast(instr)->access(), &index)) {
result.RemoveFlag(kInobjectFields);
result.AddSpecial(index);
result.AddSpecial(InobjectField(index));
} else {
result.AddAllSpecial();
for (index = 0; index < kNumberOfInobjectFields; ++index) {
result.AddSpecial(InobjectField(index));
}
}
}
return result;
......@@ -420,8 +446,15 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
}
}
}
for (int index = 0; index < num_global_vars_; ++index) {
if (side_effects.ContainsSpecial(GlobalVar(index))) {
stream->Add(separator);
separator = ", ";
stream->Add("[%p]", *global_vars_[index].handle());
}
}
for (int index = 0; index < num_inobject_fields_; ++index) {
if (side_effects.ContainsSpecial(index)) {
if (side_effects.ContainsSpecial(InobjectField(index))) {
stream->Add(separator);
separator = ", ";
inobject_fields_[index].PrintTo(stream);
......@@ -431,6 +464,29 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
}
bool SideEffectsTracker::ComputeGlobalVar(Unique<Cell> cell, int* index) {
for (int i = 0; i < num_global_vars_; ++i) {
if (cell == global_vars_[i]) {
*index = i;
return true;
}
}
if (num_global_vars_ < kNumberOfGlobalVars) {
if (FLAG_trace_gvn) {
HeapStringAllocator allocator;
StringStream stream(&allocator);
stream.Add("Tracking global var [%p] (mapped to index %d)\n",
*cell.handle(), num_global_vars_);
stream.OutputToStdOut();
}
*index = num_global_vars_;
global_vars_[num_global_vars_++] = cell;
return true;
}
return false;
}
bool SideEffectsTracker::ComputeInobjectField(HObjectAccess access,
int* index) {
for (int i = 0; i < num_inobject_fields_; ++i) {
......@@ -439,13 +495,13 @@ bool SideEffectsTracker::ComputeInobjectField(HObjectAccess access,
return true;
}
}
if (num_inobject_fields_ < SideEffects::kNumberOfSpecials) {
if (num_inobject_fields_ < kNumberOfInobjectFields) {
if (FLAG_trace_gvn) {
HeapStringAllocator allocator;
StringStream stream(&allocator);
stream.Add("Tracking inobject field access ");
access.PrintTo(&stream);
stream.Add(" (mapped to special index %d)\n", num_inobject_fields_);
stream.Add(" (mapped to index %d)\n", num_inobject_fields_);
stream.OutputToStdOut();
}
*index = num_inobject_fields_;
......
......@@ -58,7 +58,6 @@ class SideEffects V8_FINAL {
bool ContainsAnyOf(SideEffects set) const { return (bits_ & set.bits_) != 0; }
void Add(SideEffects set) { bits_ |= set.bits_; }
void AddSpecial(int special) { bits_ |= MaskSpecial(special); }
void AddAllSpecial() { bits_ |= ~static_cast<uint64_t>(0) << kNumberOfFlags; }
void RemoveFlag(GVNFlag flag) { bits_ &= ~MaskFlag(flag); }
void RemoveAll() { bits_ = 0; }
uint64_t ToIntegral() const { return bits_; }
......@@ -79,21 +78,42 @@ class SideEffects V8_FINAL {
};
// Tracks inobject field loads/stores in a fine grained fashion, and represents
// them using the "special" dynamic side effects of the SideEffects class (see
// above). This way unrelated inobject field stores don't prevent hoisting and
// merging of inobject field loads.
// Tracks global variable and inobject field loads/stores in a fine grained
// fashion, and represents them using the "special" dynamic side effects of the
// SideEffects class (see above). This way unrelated global variable/inobject
// field stores don't prevent hoisting and merging of global variable/inobject
// field loads.
class SideEffectsTracker V8_FINAL BASE_EMBEDDED {
public:
SideEffectsTracker() : num_inobject_fields_(0) {}
SideEffectsTracker() : num_global_vars_(0), num_inobject_fields_(0) {}
SideEffects ComputeChanges(HInstruction* instr);
SideEffects ComputeDependsOn(HInstruction* instr);
void PrintSideEffectsTo(StringStream* stream, SideEffects side_effects) const;
private:
bool ComputeGlobalVar(Unique<Cell> cell, int* index);
bool ComputeInobjectField(HObjectAccess access, int* index);
HObjectAccess inobject_fields_[SideEffects::kNumberOfSpecials];
static int GlobalVar(int index) {
ASSERT(index >= 0);
ASSERT(index < kNumberOfGlobalVars);
return index;
}
static int InobjectField(int index) {
ASSERT(index >= 0);
ASSERT(index < kNumberOfInobjectFields);
return index + kNumberOfGlobalVars;
}
// Track up to four global vars.
static const int kNumberOfGlobalVars = 4;
Unique<Cell> global_vars_[kNumberOfGlobalVars];
int num_global_vars_;
// Track up to n inobject fields.
static const int kNumberOfInobjectFields =
SideEffects::kNumberOfSpecials - kNumberOfGlobalVars;
HObjectAccess inobject_fields_[kNumberOfInobjectFields];
int num_inobject_fields_;
};
......
......@@ -142,8 +142,12 @@ class Unique V8_FINAL {
friend class Unique; // For comparing raw_address values.
private:
Unique<T>() : raw_address_(NULL) { }
Address raw_address_;
Handle<T> handle_;
friend class SideEffectsTracker;
};
......
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