Commit 18104111 authored by ulan@chromium.org's avatar ulan@chromium.org

Refactor GetCodeCopyFromTemplate to get a single point where objects are replaced in code.

BUG=
R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20035 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 611ea747
......@@ -86,9 +86,11 @@ Code::Kind CodeStub::GetCodeKind() const {
}
Handle<Code> CodeStub::GetCodeCopyFromTemplate(Isolate* isolate) {
Handle<Code> CodeStub::GetCodeCopy(Isolate* isolate,
const Code::FindAndReplacePattern& pattern) {
Handle<Code> ic = GetCode(isolate);
ic = isolate->factory()->CopyCode(ic);
ic->FindAndReplace(pattern);
RecordCodeGeneration(*ic, isolate);
return ic;
}
......
......@@ -144,7 +144,9 @@ class CodeStub BASE_EMBEDDED {
Handle<Code> GetCode(Isolate* isolate);
// Retrieve the code for the stub, make and return a copy of the code.
Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate);
Handle<Code> GetCodeCopy(
Isolate* isolate, const Code::FindAndReplacePattern& pattern);
static Major MajorKeyFromKey(uint32_t key) {
return static_cast<Major>(MajorKeyBits::decode(key));
}
......@@ -987,18 +989,19 @@ class StoreGlobalStub : public HandlerStub {
}
Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
GlobalObject* global,
PropertyCell* cell) {
Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate);
Handle<GlobalObject> global,
Handle<PropertyCell> cell) {
if (check_global()) {
// Replace the placeholder cell and global object map with the actual
// global cell and receiver map.
code->ReplaceNthObject(1, global_placeholder(isolate)->map(), global);
code->ReplaceNthObject(1, isolate->heap()->meta_map(), global->map());
Code::FindAndReplacePattern pattern;
pattern.Add(Handle<Map>(global_placeholder(isolate)->map()), global);
pattern.Add(isolate->factory()->meta_map(), Handle<Map>(global->map()));
pattern.Add(isolate->factory()->global_property_cell_map(), cell);
return CodeStub::GetCodeCopy(isolate, pattern);
} else {
Code::FindAndReplacePattern pattern;
pattern.Add(isolate->factory()->global_property_cell_map(), cell);
return CodeStub::GetCodeCopy(isolate, pattern);
}
Map* cell_map = isolate->heap()->global_property_cell_map();
code->ReplaceNthObject(1, cell_map, cell);
return code;
}
virtual Code::Kind kind() const { return Code::STORE_IC; }
......@@ -1183,10 +1186,9 @@ class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub {
Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
Handle<AllocationSite> allocation_site) {
Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate);
// Replace the placeholder oddball with the actual allocation site.
code->ReplaceNthObject(1, isolate->heap()->oddball_map(), *allocation_site);
return code;
Code::FindAndReplacePattern pattern;
pattern.Add(isolate->factory()->oddball_map(), allocation_site);
return CodeStub::GetCodeCopy(isolate, pattern);
}
virtual Code::Kind GetCodeKind() const V8_OVERRIDE {
......
......@@ -1349,7 +1349,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
StoreGlobalStub stub(
union_type->IsConstant(), receiver->IsJSGlobalProxy());
Handle<Code> code = stub.GetCodeCopyFromTemplate(
isolate(), *global, *cell);
isolate(), global, cell);
// TODO(verwaest): Move caching of these NORMAL stubs outside as well.
HeapObject::UpdateMapCodeCache(receiver, name, code);
return code;
......
......@@ -4595,6 +4595,24 @@ bool Code::IsWeakObjectInOptimizedCode(Object* object) {
}
class Code::FindAndReplacePattern {
public:
FindAndReplacePattern() : count_(0) { }
void Add(Handle<Map> map_to_find, Handle<Object> obj_to_replace) {
ASSERT(count_ < kMaxCount);
find_[count_] = map_to_find;
replace_[count_] = obj_to_replace;
++count_;
}
private:
static const int kMaxCount = 4;
int count_;
Handle<Map> find_[kMaxCount];
Handle<Object> replace_[kMaxCount];
friend class Code;
};
Object* Map::prototype() {
return READ_FIELD(this, kPrototypeOffset);
}
......
......@@ -10513,21 +10513,20 @@ Map* Code::FindFirstMap() {
}
void Code::ReplaceNthObject(int n,
Map* match_map,
Object* replace_with) {
void Code::FindAndReplace(const FindAndReplacePattern& pattern) {
ASSERT(is_inline_cache_stub() || is_handler());
DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32);
int current_pattern = 0;
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
Object* object = info->target_object();
if (object->IsHeapObject()) {
if (HeapObject::cast(object)->map() == match_map) {
if (--n == 0) {
info->set_target_object(replace_with);
return;
}
Map* map = HeapObject::cast(object)->map();
if (map == *pattern.find_[current_pattern]) {
info->set_target_object(*pattern.replace_[current_pattern]);
if (++current_pattern == pattern.count_) return;
}
}
}
......@@ -10562,11 +10561,6 @@ void Code::FindAllTypes(TypeHandleList* types) {
}
void Code::ReplaceFirstMap(Map* replace_with) {
ReplaceNthObject(1, GetHeap()->meta_map(), replace_with);
}
Code* Code::FindFirstHandler() {
ASSERT(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
......@@ -10612,21 +10606,6 @@ Name* Code::FindFirstName() {
}
void Code::ReplaceNthCell(int n, Cell* replace_with) {
ASSERT(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::CELL);
for (RelocIterator it(this, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
if (--n == 0) {
info->set_target_cell(replace_with);
return;
}
}
UNREACHABLE();
}
void Code::ClearInlineCaches() {
ClearInlineCaches(NULL);
}
......
......@@ -5379,7 +5379,6 @@ class Code: public HeapObject {
// Find an object in a stub with a specified map
Object* FindNthObject(int n, Map* match_map);
void ReplaceNthObject(int n, Map* match_map, Object* replace_with);
// Find the first allocation site in an IC stub.
AllocationSite* FindFirstAllocationSite();
......@@ -5388,7 +5387,6 @@ class Code: public HeapObject {
Map* FindFirstMap();
void FindAllMaps(MapHandleList* maps);
void FindAllTypes(TypeHandleList* types);
void ReplaceFirstMap(Map* replace);
// Find the first handler in an IC stub.
Code* FindFirstHandler();
......@@ -5400,7 +5398,12 @@ class Code: public HeapObject {
// Find the first name in an IC stub.
Name* FindFirstName();
void ReplaceNthCell(int n, Cell* replace_with);
class FindAndReplacePattern;
// For each (map-to-find, object-to-replace) pair in the pattern, this
// function replaces the corresponding placeholder in the code with the
// object-to-replace. The function assumes that pairs in the pattern come in
// the same order as the placeholders in the code.
void FindAndReplace(const FindAndReplacePattern& pattern);
// The entire code object including its header is copied verbatim to the
// snapshot so that it can be written in one, fast, memcpy during
......
......@@ -333,8 +333,9 @@ Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
if (!cached_ic.is_null()) return cached_ic;
}
Handle<Code> ic = stub.GetCodeCopyFromTemplate(isolate_);
ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map);
Code::FindAndReplacePattern pattern;
pattern.Add(isolate_->factory()->meta_map(), receiver_map);
Handle<Code> ic = stub.GetCodeCopy(isolate_, pattern);
if (!receiver_map->is_shared()) {
Map::UpdateCodeCache(receiver_map, name, ic);
......
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