Commit c759a3d8 authored by yangguo's avatar yangguo Committed by Commit bot

[serializer] small fixes for blink snapshot.

Changes include:
 - Adding V8_EXPORT macro for SnapshotCreator
 - Removing outdated DCHECKs.
 - Allow nullptr as external reference. This required a...
 - Refactoring of hashmaps used by the serializer.
 - Remove external references for counters. These are not used
   anywhere for isolates that are being serialized.
 - Put template infos into the partial snapshot cache.
 - Remove unnecessary presubmit check for external references.
   mksnapshot crashes if external references are missing.

R=jochen@chromium.org, vogelheim@chromium.org
BUG=chromium:617892

Review-Url: https://codereview.chromium.org/2490783004
Cr-Commit-Position: refs/heads/master@{#40949}
parent a9f553ba
...@@ -67,7 +67,6 @@ def _V8PresubmitChecks(input_api, output_api): ...@@ -67,7 +67,6 @@ def _V8PresubmitChecks(input_api, output_api):
input_api.PresubmitLocalPath(), 'tools')) input_api.PresubmitLocalPath(), 'tools'))
from presubmit import CppLintProcessor from presubmit import CppLintProcessor
from presubmit import SourceProcessor from presubmit import SourceProcessor
from presubmit import CheckExternalReferenceRegistration
from presubmit import CheckAuthorizedAuthor from presubmit import CheckAuthorizedAuthor
from presubmit import CheckStatusFiles from presubmit import CheckStatusFiles
...@@ -78,9 +77,6 @@ def _V8PresubmitChecks(input_api, output_api): ...@@ -78,9 +77,6 @@ def _V8PresubmitChecks(input_api, output_api):
results.append(output_api.PresubmitError( results.append(output_api.PresubmitError(
"Copyright header, trailing whitespaces and two empty lines " \ "Copyright header, trailing whitespaces and two empty lines " \
"between declarations check failed")) "between declarations check failed"))
if not CheckExternalReferenceRegistration(input_api.PresubmitLocalPath()):
results.append(output_api.PresubmitError(
"External references registration check failed"))
if not CheckStatusFiles(input_api.PresubmitLocalPath()): if not CheckStatusFiles(input_api.PresubmitLocalPath()):
results.append(output_api.PresubmitError("Status file check failed")) results.append(output_api.PresubmitError("Status file check failed"))
results.extend(CheckAuthorizedAuthor(input_api, output_api)) results.extend(CheckAuthorizedAuthor(input_api, output_api))
......
...@@ -7575,7 +7575,7 @@ class V8_EXPORT V8 { ...@@ -7575,7 +7575,7 @@ class V8_EXPORT V8 {
/** /**
* Helper class to create a snapshot data blob. * Helper class to create a snapshot data blob.
*/ */
class SnapshotCreator { class V8_EXPORT SnapshotCreator {
public: public:
enum class FunctionCodeHandling { kClear, kKeep }; enum class FunctionCodeHandling { kClear, kKeep };
......
...@@ -13,7 +13,7 @@ namespace internal { ...@@ -13,7 +13,7 @@ namespace internal {
RootIndexMap::RootIndexMap(Isolate* isolate) { RootIndexMap::RootIndexMap(Isolate* isolate) {
map_ = isolate->root_index_map(); map_ = isolate->root_index_map();
if (map_ != NULL) return; if (map_ != NULL) return;
map_ = new base::HashMap(); map_ = new HeapObjectToIndexHashMap();
for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) { for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) {
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i); Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
Object* root = isolate->heap()->root(root_index); Object* root = isolate->heap()->root(root_index);
...@@ -22,12 +22,12 @@ RootIndexMap::RootIndexMap(Isolate* isolate) { ...@@ -22,12 +22,12 @@ RootIndexMap::RootIndexMap(Isolate* isolate) {
// not be referenced through the root list in the snapshot. // not be referenced through the root list in the snapshot.
if (isolate->heap()->RootCanBeTreatedAsConstant(root_index)) { if (isolate->heap()->RootCanBeTreatedAsConstant(root_index)) {
HeapObject* heap_object = HeapObject::cast(root); HeapObject* heap_object = HeapObject::cast(root);
base::HashMap::Entry* entry = LookupEntry(map_, heap_object, false); Maybe<uint32_t> maybe_index = map_->Get(heap_object);
if (entry != NULL) { if (maybe_index.IsJust()) {
// Some are initialized to a previous value in the root list. // Some are initialized to a previous value in the root list.
DCHECK_LT(GetValue(entry), i); DCHECK_LT(maybe_index.FromJust(), i);
} else { } else {
SetValue(LookupEntry(map_, heap_object, true), i); map_->Set(heap_object, i);
} }
} else { } else {
// Immortal immovable root objects are constant and allocated on the first // Immortal immovable root objects are constant and allocated on the first
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_ADDRESS_MAP_H_ #ifndef V8_ADDRESS_MAP_H_
#define V8_ADDRESS_MAP_H_ #define V8_ADDRESS_MAP_H_
#include "include/v8.h"
#include "src/assert-scope.h" #include "src/assert-scope.h"
#include "src/base/hashmap.h" #include "src/base/hashmap.h"
#include "src/objects.h" #include "src/objects.h"
...@@ -12,49 +13,52 @@ ...@@ -12,49 +13,52 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class AddressMapBase { template <typename Type>
protected: class PointerToIndexHashMap
static void SetValue(base::HashMap::Entry* entry, uint32_t v) { : public base::TemplateHashMapImpl<uintptr_t, uint32_t,
entry->value = reinterpret_cast<void*>(v); base::KeyEqualityMatcher<intptr_t>,
} base::DefaultAllocationPolicy> {
public:
typedef base::TemplateHashMapEntry<uintptr_t, uint32_t> Entry;
static uint32_t GetValue(base::HashMap::Entry* entry) { inline void Set(Type value, uint32_t index) {
return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); uintptr_t key = Key(value);
LookupOrInsert(key, Hash(key))->value = index;
} }
inline static base::HashMap::Entry* LookupEntry(base::HashMap* map, inline Maybe<uint32_t> Get(Type value) const {
HeapObject* obj, uintptr_t key = Key(value);
bool insert) { Entry* entry = Lookup(key, Hash(key));
if (insert) { if (entry == nullptr) return Nothing<uint32_t>();
map->LookupOrInsert(Key(obj), Hash(obj)); return Just(entry->value);
}
return map->Lookup(Key(obj), Hash(obj));
} }
private: private:
static uint32_t Hash(HeapObject* obj) { static uintptr_t Key(Type value) {
return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); return reinterpret_cast<uintptr_t>(value);
} }
static void* Key(HeapObject* obj) { static uint32_t Hash(uintptr_t key) {
return reinterpret_cast<void*>(obj->address()); return static_cast<uint32_t>(key >> kPointerSizeLog2);
} }
}; };
class RootIndexMap : public AddressMapBase { class AddressToIndexHashMap : public PointerToIndexHashMap<Address> {};
class HeapObjectToIndexHashMap : public PointerToIndexHashMap<HeapObject*> {};
class RootIndexMap {
public: public:
explicit RootIndexMap(Isolate* isolate); explicit RootIndexMap(Isolate* isolate);
static const int kInvalidRootIndex = -1; static const int kInvalidRootIndex = -1;
int Lookup(HeapObject* obj) { int Lookup(HeapObject* obj) {
base::HashMap::Entry* entry = LookupEntry(map_, obj, false); Maybe<uint32_t> maybe_index = map_->Get(obj);
if (entry) return GetValue(entry); return maybe_index.IsJust() ? maybe_index.FromJust() : kInvalidRootIndex;
return kInvalidRootIndex;
} }
private: private:
base::HashMap* map_; HeapObjectToIndexHashMap* map_;
DISALLOW_COPY_AND_ASSIGN(RootIndexMap); DISALLOW_COPY_AND_ASSIGN(RootIndexMap);
}; };
...@@ -186,21 +190,21 @@ class SerializerReference { ...@@ -186,21 +190,21 @@ class SerializerReference {
// Mapping objects to their location after deserialization. // Mapping objects to their location after deserialization.
// This is used during building, but not at runtime by V8. // This is used during building, but not at runtime by V8.
class SerializerReferenceMap : public AddressMapBase { class SerializerReferenceMap {
public: public:
SerializerReferenceMap() SerializerReferenceMap()
: no_allocation_(), map_(), attached_reference_index_(0) {} : no_allocation_(), map_(), attached_reference_index_(0) {}
SerializerReference Lookup(HeapObject* obj) { SerializerReference Lookup(HeapObject* obj) {
base::HashMap::Entry* entry = LookupEntry(&map_, obj, false); Maybe<uint32_t> maybe_index = map_.Get(obj);
return entry ? SerializerReference(GetValue(entry)) : SerializerReference(); return maybe_index.IsJust() ? SerializerReference(maybe_index.FromJust())
: SerializerReference();
} }
void Add(HeapObject* obj, SerializerReference b) { void Add(HeapObject* obj, SerializerReference b) {
DCHECK(b.is_valid()); DCHECK(b.is_valid());
DCHECK_NULL(LookupEntry(&map_, obj, false)); DCHECK(map_.Get(obj).IsNothing());
base::HashMap::Entry* entry = LookupEntry(&map_, obj, true); map_.Set(obj, b.bitfield_);
SetValue(entry, b.bitfield_);
} }
SerializerReference AddAttachedReference(HeapObject* attached_reference) { SerializerReference AddAttachedReference(HeapObject* attached_reference) {
...@@ -212,7 +216,7 @@ class SerializerReferenceMap : public AddressMapBase { ...@@ -212,7 +216,7 @@ class SerializerReferenceMap : public AddressMapBase {
private: private:
DisallowHeapAllocation no_allocation_; DisallowHeapAllocation no_allocation_;
base::HashMap map_; HeapObjectToIndexHashMap map_;
int attached_reference_index_; int attached_reference_index_;
DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap); DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap);
}; };
......
...@@ -1240,7 +1240,6 @@ Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler( ...@@ -1240,7 +1240,6 @@ Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data, experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
v8::Local<Signature> signature, int length) { v8::Local<Signature> signature, int length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
DCHECK(!i_isolate->serializer_enabled());
LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler); LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler);
ENTER_V8(i_isolate); ENTER_V8(i_isolate);
return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature, return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
...@@ -1251,7 +1250,6 @@ Local<FunctionTemplate> FunctionTemplate::NewWithCache( ...@@ -1251,7 +1250,6 @@ Local<FunctionTemplate> FunctionTemplate::NewWithCache(
Isolate* isolate, FunctionCallback callback, Local<Private> cache_property, Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
Local<Value> data, Local<Signature> signature, int length) { Local<Value> data, Local<Signature> signature, int length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
DCHECK(!i_isolate->serializer_enabled());
LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler); LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler);
ENTER_V8(i_isolate); ENTER_V8(i_isolate);
return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature, return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
......
...@@ -31,10 +31,11 @@ ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) { ...@@ -31,10 +31,11 @@ ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) {
} }
ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) { ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
// nullptr is preserved through serialization/deserialization.
Add(nullptr, "nullptr");
AddReferences(isolate); AddReferences(isolate);
AddBuiltins(isolate); AddBuiltins(isolate);
AddRuntimeFunctions(isolate); AddRuntimeFunctions(isolate);
AddStatCounters(isolate);
AddIsolateAddresses(isolate); AddIsolateAddresses(isolate);
AddAccessors(isolate); AddAccessors(isolate);
AddStubCache(isolate); AddStubCache(isolate);
...@@ -73,8 +74,6 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) { ...@@ -73,8 +74,6 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
Add(ExternalReference::isolate_address(isolate).address(), "isolate"); Add(ExternalReference::isolate_address(isolate).address(), "isolate");
Add(ExternalReference::interpreter_dispatch_table_address(isolate).address(), Add(ExternalReference::interpreter_dispatch_table_address(isolate).address(),
"Interpreter::dispatch_table_address"); "Interpreter::dispatch_table_address");
Add(ExternalReference::interpreter_dispatch_counters(isolate).address(),
"Interpreter::interpreter_dispatch_counters");
Add(ExternalReference::address_of_negative_infinity().address(), Add(ExternalReference::address_of_negative_infinity().address(),
"LDoubleConstant::negative_infinity"); "LDoubleConstant::negative_infinity");
Add(ExternalReference::power_double_double_function(isolate).address(), Add(ExternalReference::power_double_double_function(isolate).address(),
...@@ -315,32 +314,6 @@ void ExternalReferenceTable::AddRuntimeFunctions(Isolate* isolate) { ...@@ -315,32 +314,6 @@ void ExternalReferenceTable::AddRuntimeFunctions(Isolate* isolate) {
} }
} }
void ExternalReferenceTable::AddStatCounters(Isolate* isolate) {
// Stat counters
struct StatsRefTableEntry {
StatsCounter* (Counters::*counter)();
const char* name;
};
static const StatsRefTableEntry stats_ref_table[] = {
#define COUNTER_ENTRY(name, caption) {&Counters::name, "Counters::" #name},
STATS_COUNTER_LIST_1(COUNTER_ENTRY) STATS_COUNTER_LIST_2(COUNTER_ENTRY)
#undef COUNTER_ENTRY
};
Counters* counters = isolate->counters();
for (unsigned i = 0; i < arraysize(stats_ref_table); ++i) {
// To make sure the indices are not dependent on whether counters are
// enabled, use a dummy address as filler.
Address address = NotAvailable();
StatsCounter* counter = (counters->*(stats_ref_table[i].counter))();
if (counter->Enabled()) {
address = reinterpret_cast<Address>(counter->GetInternalPointer());
}
Add(address, stats_ref_table[i].name);
}
}
void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate) { void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate) {
// Top addresses // Top addresses
static const char* address_names[] = { static const char* address_names[] = {
......
...@@ -19,11 +19,9 @@ class ExternalReferenceTable { ...@@ -19,11 +19,9 @@ class ExternalReferenceTable {
public: public:
static ExternalReferenceTable* instance(Isolate* isolate); static ExternalReferenceTable* instance(Isolate* isolate);
int size() const { return refs_.length(); } uint32_t size() const { return static_cast<uint32_t>(refs_.length()); }
Address address(int i) { return refs_[i].address; } Address address(uint32_t i) { return refs_[i].address; }
const char* name(int i) { return refs_[i].name; } const char* name(uint32_t i) { return refs_[i].name; }
inline static Address NotAvailable() { return NULL; }
static const int kDeoptTableSerializeEntryCount = 64; static const int kDeoptTableSerializeEntryCount = 64;
...@@ -43,7 +41,6 @@ class ExternalReferenceTable { ...@@ -43,7 +41,6 @@ class ExternalReferenceTable {
void AddReferences(Isolate* isolate); void AddReferences(Isolate* isolate);
void AddBuiltins(Isolate* isolate); void AddBuiltins(Isolate* isolate);
void AddRuntimeFunctions(Isolate* isolate); void AddRuntimeFunctions(Isolate* isolate);
void AddStatCounters(Isolate* isolate);
void AddIsolateAddresses(Isolate* isolate); void AddIsolateAddresses(Isolate* isolate);
void AddAccessors(Isolate* isolate); void AddAccessors(Isolate* isolate);
void AddStubCache(Isolate* isolate); void AddStubCache(Isolate* isolate);
......
...@@ -34,6 +34,7 @@ class RandomNumberGenerator; ...@@ -34,6 +34,7 @@ class RandomNumberGenerator;
namespace internal { namespace internal {
class AccessCompilerData; class AccessCompilerData;
class AddressToIndexHashMap;
class BasicBlockProfiler; class BasicBlockProfiler;
class Bootstrapper; class Bootstrapper;
class CancelableTaskManager; class CancelableTaskManager;
...@@ -59,6 +60,7 @@ class ExternalCallbackScope; ...@@ -59,6 +60,7 @@ class ExternalCallbackScope;
class ExternalReferenceTable; class ExternalReferenceTable;
class Factory; class Factory;
class HandleScopeImplementer; class HandleScopeImplementer;
class HeapObjectToIndexHashMap;
class HeapProfiler; class HeapProfiler;
class HStatistics; class HStatistics;
class HTracer; class HTracer;
...@@ -400,8 +402,8 @@ typedef List<HeapObject*> DebugObjectCache; ...@@ -400,8 +402,8 @@ typedef List<HeapObject*> DebugObjectCache;
V(Object*, string_stream_current_security_token, nullptr) \ V(Object*, string_stream_current_security_token, nullptr) \
V(ExternalReferenceTable*, external_reference_table, nullptr) \ V(ExternalReferenceTable*, external_reference_table, nullptr) \
V(intptr_t*, api_external_references, nullptr) \ V(intptr_t*, api_external_references, nullptr) \
V(base::HashMap*, external_reference_map, nullptr) \ V(AddressToIndexHashMap*, external_reference_map, nullptr) \
V(base::HashMap*, root_index_map, nullptr) \ V(HeapObjectToIndexHashMap*, root_index_map, nullptr) \
V(v8::DeserializeInternalFieldsCallback, \ V(v8::DeserializeInternalFieldsCallback, \
deserialize_internal_fields_callback, nullptr) \ deserialize_internal_fields_callback, nullptr) \
V(int, pending_microtask_count, 0) \ V(int, pending_microtask_count, 0) \
......
...@@ -528,7 +528,7 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space, ...@@ -528,7 +528,7 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
int skip = source_.GetInt(); \ int skip = source_.GetInt(); \
current = reinterpret_cast<Object**>( \ current = reinterpret_cast<Object**>( \
reinterpret_cast<Address>(current) + skip); \ reinterpret_cast<Address>(current) + skip); \
int reference_id = source_.GetInt(); \ uint32_t reference_id = static_cast<uint32_t>(source_.GetInt()); \
Address address = external_reference_table_->address(reference_id); \ Address address = external_reference_table_->address(reference_id); \
new_object = reinterpret_cast<Object*>(address); \ new_object = reinterpret_cast<Object*>(address); \
} else if (where == kAttachedReference) { \ } else if (where == kAttachedReference) { \
......
...@@ -118,6 +118,7 @@ bool PartialSerializer::ShouldBeInThePartialSnapshotCache(HeapObject* o) { ...@@ -118,6 +118,7 @@ bool PartialSerializer::ShouldBeInThePartialSnapshotCache(HeapObject* o) {
DCHECK(!o->IsScript()); DCHECK(!o->IsScript());
return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() || return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() ||
o->IsCode() || o->IsScopeInfo() || o->IsAccessorInfo() || o->IsCode() || o->IsScopeInfo() || o->IsAccessorInfo() ||
o->IsTemplateInfo() ||
o->map() == o->map() ==
startup_serializer_->isolate()->heap()->fixed_cow_array_map(); startup_serializer_->isolate()->heap()->fixed_cow_array_map();
} }
......
...@@ -18,27 +18,24 @@ namespace internal { ...@@ -18,27 +18,24 @@ namespace internal {
ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) { ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
map_ = isolate->external_reference_map(); map_ = isolate->external_reference_map();
if (map_ != NULL) return; if (map_ != nullptr) return;
map_ = new base::HashMap(); map_ = new AddressToIndexHashMap();
ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate); ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
for (int i = 0; i < table->size(); ++i) { for (uint32_t i = 0; i < table->size(); ++i) {
Address addr = table->address(i); Address addr = table->address(i);
if (addr == ExternalReferenceTable::NotAvailable()) continue;
// We expect no duplicate external references entries in the table. // We expect no duplicate external references entries in the table.
// AccessorRefTable getter may have duplicates, indicated by an empty string // AccessorRefTable getter may have duplicates, indicated by an empty string
// as name. // as name.
DCHECK(table->name(i)[0] == '\0' || DCHECK(table->name(i)[0] == '\0' || map_->Get(addr).IsNothing());
map_->Lookup(addr, Hash(addr)) == nullptr); map_->Set(addr, i);
map_->LookupOrInsert(addr, Hash(addr))->value = reinterpret_cast<void*>(i); DCHECK(map_->Get(addr).IsJust());
} }
isolate->set_external_reference_map(map_); isolate->set_external_reference_map(map_);
} }
uint32_t ExternalReferenceEncoder::Encode(Address address) const { uint32_t ExternalReferenceEncoder::Encode(Address address) const {
DCHECK_NOT_NULL(address); Maybe<uint32_t> maybe_index = map_->Get(address);
base::HashMap::Entry* entry = if (maybe_index.IsNothing()) {
const_cast<base::HashMap*>(map_)->Lookup(address, Hash(address));
if (entry == nullptr) {
void* function_addr = address; void* function_addr = address;
v8::base::OS::PrintError("Unknown external reference %p.\n", function_addr); v8::base::OS::PrintError("Unknown external reference %p.\n", function_addr);
#ifdef SYMBOLIZE_FUNCTION #ifdef SYMBOLIZE_FUNCTION
...@@ -46,16 +43,15 @@ uint32_t ExternalReferenceEncoder::Encode(Address address) const { ...@@ -46,16 +43,15 @@ uint32_t ExternalReferenceEncoder::Encode(Address address) const {
#endif // SYMBOLIZE_FUNCTION #endif // SYMBOLIZE_FUNCTION
v8::base::OS::Abort(); v8::base::OS::Abort();
} }
return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); return maybe_index.FromJust();
} }
const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
Address address) const { Address address) const {
base::HashMap::Entry* entry = Maybe<uint32_t> maybe_index = map_->Get(address);
const_cast<base::HashMap*>(map_)->Lookup(address, Hash(address)); if (maybe_index.IsNothing()) return "<unknown>";
if (entry == NULL) return "<unknown>"; return ExternalReferenceTable::instance(isolate)->name(
uint32_t i = static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); maybe_index.FromJust());
return ExternalReferenceTable::instance(isolate)->name(i);
} }
void SerializedData::AllocateData(int size) { void SerializedData::AllocateData(int size) {
......
...@@ -23,12 +23,7 @@ class ExternalReferenceEncoder { ...@@ -23,12 +23,7 @@ class ExternalReferenceEncoder {
const char* NameOfAddress(Isolate* isolate, Address address) const; const char* NameOfAddress(Isolate* isolate, Address address) const;
private: private:
static uint32_t Hash(Address key) { AddressToIndexHashMap* map_;
return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key) >>
kPointerSizeLog2);
}
base::HashMap* map_;
DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder); DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
}; };
......
...@@ -623,6 +623,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { ...@@ -623,6 +623,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
sink_->PutInt(skip, "SkipB4ExternalRef"); sink_->PutInt(skip, "SkipB4ExternalRef");
Address target = rinfo->target_external_reference(); Address target = rinfo->target_external_reference();
DCHECK_NOT_NULL(target); // Code does not reference null.
sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
bytes_processed_so_far_ += rinfo->target_address_size(); bytes_processed_so_far_ += rinfo->target_address_size();
} }
......
...@@ -30,25 +30,26 @@ class StartupSerializer : public Serializer { ...@@ -30,25 +30,26 @@ class StartupSerializer : public Serializer {
int PartialSnapshotCacheIndex(HeapObject* o); int PartialSnapshotCacheIndex(HeapObject* o);
private: private:
class PartialCacheIndexMap : public AddressMapBase { class PartialCacheIndexMap {
public: public:
PartialCacheIndexMap() : map_(), next_index_(0) {} PartialCacheIndexMap() : map_(), next_index_(0) {}
// Lookup object in the map. Return its index if found, or create // Lookup object in the map. Return its index if found, or create
// a new entry with new_index as value, and return kInvalidIndex. // a new entry with new_index as value, and return kInvalidIndex.
bool LookupOrInsert(HeapObject* obj, int* index_out) { bool LookupOrInsert(HeapObject* obj, int* index_out) {
base::HashMap::Entry* entry = LookupEntry(&map_, obj, false); Maybe<uint32_t> maybe_index = map_.Get(obj);
if (entry != NULL) { if (maybe_index.IsJust()) {
*index_out = GetValue(entry); *index_out = maybe_index.FromJust();
return true; return true;
} }
*index_out = next_index_; *index_out = next_index_;
SetValue(LookupEntry(&map_, obj, true), next_index_++); map_.Set(obj, next_index_++);
return false; return false;
} }
private: private:
base::HashMap map_; DisallowHeapAllocation no_allocation_;
HeapObjectToIndexHashMap map_;
int next_index_; int next_index_;
DISALLOW_COPY_AND_ASSIGN(PartialCacheIndexMap); DISALLOW_COPY_AND_ASSIGN(PartialCacheIndexMap);
......
...@@ -2022,11 +2022,15 @@ void SerializedCallbackReplacement( ...@@ -2022,11 +2022,15 @@ void SerializedCallbackReplacement(
args.GetReturnValue().Set(v8_num(1337)); args.GetReturnValue().Set(v8_num(1337));
} }
static int serialized_static_field = 314;
intptr_t original_external_references[] = { intptr_t original_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallback), 0}; reinterpret_cast<intptr_t>(SerializedCallback),
reinterpret_cast<intptr_t>(&serialized_static_field), 0};
intptr_t replaced_external_references[] = { intptr_t replaced_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallbackReplacement), 0}; reinterpret_cast<intptr_t>(SerializedCallbackReplacement),
reinterpret_cast<intptr_t>(&serialized_static_field), 0};
TEST(SnapshotCreatorExternalReferences) { TEST(SnapshotCreatorExternalReferences) {
DisableAlwaysOpt(); DisableAlwaysOpt();
...@@ -2142,7 +2146,6 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2142,7 +2146,6 @@ TEST(SnapshotCreatorTemplates) {
InternalFieldData* a1 = new InternalFieldData{11}; InternalFieldData* a1 = new InternalFieldData{11};
InternalFieldData* b0 = new InternalFieldData{20}; InternalFieldData* b0 = new InternalFieldData{20};
InternalFieldData* c0 = new InternalFieldData{30}; InternalFieldData* c0 = new InternalFieldData{30};
InternalFieldData* c1 = new InternalFieldData{31};
v8::SnapshotCreator creator(original_external_references); v8::SnapshotCreator creator(original_external_references);
v8::Isolate* isolate = creator.GetIsolate(); v8::Isolate* isolate = creator.GetIsolate();
...@@ -2158,7 +2161,7 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2158,7 +2161,7 @@ TEST(SnapshotCreatorTemplates) {
v8::Context::New(isolate, no_extension, global_template); v8::Context::New(isolate, no_extension, global_template);
v8::Local<v8::ObjectTemplate> object_template = v8::Local<v8::ObjectTemplate> object_template =
v8::ObjectTemplate::New(isolate); v8::ObjectTemplate::New(isolate);
object_template->SetInternalFieldCount(2); object_template->SetInternalFieldCount(3);
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42); ExpectInt32("f()", 42);
...@@ -2169,12 +2172,17 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2169,12 +2172,17 @@ TEST(SnapshotCreatorTemplates) {
object_template->NewInstance(context).ToLocalChecked(); object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::Object> c = v8::Local<v8::Object> c =
object_template->NewInstance(context).ToLocalChecked(); object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::External> null_external =
v8::External::New(isolate, nullptr);
v8::Local<v8::External> field_external =
v8::External::New(isolate, &serialized_static_field);
a->SetInternalField(0, b); a->SetInternalField(0, b);
a->SetAlignedPointerInInternalField(1, a1); a->SetAlignedPointerInInternalField(1, a1);
b->SetAlignedPointerInInternalField(0, b0); b->SetAlignedPointerInInternalField(0, b0);
b->SetInternalField(1, c); b->SetInternalField(1, c);
c->SetAlignedPointerInInternalField(0, c0); c->SetAlignedPointerInInternalField(0, c0);
c->SetAlignedPointerInInternalField(1, c1); c->SetInternalField(1, null_external);
c->SetInternalField(2, field_external);
CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust()); CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust());
CHECK_EQ(0u, creator.AddContext(context)); CHECK_EQ(0u, creator.AddContext(context));
...@@ -2186,7 +2194,6 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2186,7 +2194,6 @@ TEST(SnapshotCreatorTemplates) {
delete a1; delete a1;
delete b0; delete b0;
delete c1;
delete c0; delete c0;
} }
...@@ -2239,19 +2246,28 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2239,19 +2246,28 @@ TEST(SnapshotCreatorTemplates) {
a->GetInternalField(0)->ToObject(context).ToLocalChecked(); a->GetInternalField(0)->ToObject(context).ToLocalChecked();
InternalFieldData* a1 = reinterpret_cast<InternalFieldData*>( InternalFieldData* a1 = reinterpret_cast<InternalFieldData*>(
a->GetAlignedPointerFromInternalField(1)); a->GetAlignedPointerFromInternalField(1));
v8::Local<v8::Value> a2 = a->GetInternalField(2);
InternalFieldData* b0 = reinterpret_cast<InternalFieldData*>( InternalFieldData* b0 = reinterpret_cast<InternalFieldData*>(
b->GetAlignedPointerFromInternalField(0)); b->GetAlignedPointerFromInternalField(0));
v8::Local<v8::Object> c = v8::Local<v8::Object> c =
b->GetInternalField(1)->ToObject(context).ToLocalChecked(); b->GetInternalField(1)->ToObject(context).ToLocalChecked();
v8::Local<v8::Value> b2 = b->GetInternalField(2);
InternalFieldData* c0 = reinterpret_cast<InternalFieldData*>( InternalFieldData* c0 = reinterpret_cast<InternalFieldData*>(
c->GetAlignedPointerFromInternalField(0)); c->GetAlignedPointerFromInternalField(0));
InternalFieldData* c1 = reinterpret_cast<InternalFieldData*>( v8::Local<v8::Value> c1 = c->GetInternalField(1);
c->GetAlignedPointerFromInternalField(1)); v8::Local<v8::Value> c2 = c->GetInternalField(2);
CHECK_EQ(11u, a1->data); CHECK_EQ(11u, a1->data);
CHECK(a2->IsUndefined());
CHECK_EQ(20u, b0->data); CHECK_EQ(20u, b0->data);
CHECK(b2->IsUndefined());
CHECK_EQ(30u, c0->data); CHECK_EQ(30u, c0->data);
CHECK_EQ(31u, c1->data); CHECK(c1->IsExternal());
CHECK_NULL(v8::Local<v8::External>::Cast(c1)->Value());
CHECK_EQ(static_cast<void*>(&serialized_static_field),
v8::Local<v8::External>::Cast(c2)->Value());
// Accessing out of bound returns empty MaybeHandle. // Accessing out of bound returns empty MaybeHandle.
CHECK(v8::ObjectTemplate::FromSnapshot(isolate, 2).IsEmpty()); CHECK(v8::ObjectTemplate::FromSnapshot(isolate, 2).IsEmpty());
...@@ -2260,7 +2276,6 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2260,7 +2276,6 @@ TEST(SnapshotCreatorTemplates) {
delete a1; delete a1;
delete b0; delete b0;
delete c1;
delete c0; delete c0;
} }
......
#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
import os
import sys
DECLARE_FILE = "src/assembler.h"
REGISTER_FILE = "src/external-reference-table.cc"
DECLARE_RE = re.compile("\s*static ExternalReference ([^(]+)\(")
REGISTER_RE = re.compile("\s*Add\(ExternalReference::([^(]+)\(")
WORKSPACE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
# Ignore those.
BLACKLISTED = [
"fixed_typed_array_base_data_offset",
"page_flags",
"math_exp_constants",
"math_exp_log_table",
"ForDeoptEntry",
]
def Find(filename, re):
references = []
with open(filename, "r") as f:
for line in f:
match = re.match(line)
if match:
references.append(match.group(1))
return references
def Main():
declarations = Find(DECLARE_FILE, DECLARE_RE)
registrations = Find(REGISTER_FILE, REGISTER_RE)
difference = list(set(declarations) - set(registrations) - set(BLACKLISTED))
for reference in difference:
print("Declared but not registered: ExternalReference::%s" % reference)
return len(difference) > 0
if __name__ == "__main__":
sys.exit(Main())
...@@ -396,13 +396,6 @@ class SourceProcessor(SourceFileProcessor): ...@@ -396,13 +396,6 @@ class SourceProcessor(SourceFileProcessor):
print "Total violating files: %s" % violations print "Total violating files: %s" % violations
return success return success
def CheckExternalReferenceRegistration(workspace):
code = subprocess.call(
[sys.executable, join(workspace, "tools", "external-reference-check.py")])
return code == 0
def _CheckStatusFileForDuplicateKeys(filepath): def _CheckStatusFileForDuplicateKeys(filepath):
comma_space_bracket = re.compile(", *]") comma_space_bracket = re.compile(", *]")
lines = [] lines = []
...@@ -503,7 +496,6 @@ def Main(): ...@@ -503,7 +496,6 @@ def Main():
print "Running copyright header, trailing whitespaces and " \ print "Running copyright header, trailing whitespaces and " \
"two empty lines between declarations check..." "two empty lines between declarations check..."
success &= SourceProcessor().Run(workspace) success &= SourceProcessor().Run(workspace)
success &= CheckExternalReferenceRegistration(workspace)
success &= CheckStatusFiles(workspace) success &= CheckStatusFiles(workspace)
if success: if success:
return 0 return 0
......
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