[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}
This commit is contained in:
parent
a9f553bada
commit
c759a3d847
@ -67,7 +67,6 @@ def _V8PresubmitChecks(input_api, output_api):
|
||||
input_api.PresubmitLocalPath(), 'tools'))
|
||||
from presubmit import CppLintProcessor
|
||||
from presubmit import SourceProcessor
|
||||
from presubmit import CheckExternalReferenceRegistration
|
||||
from presubmit import CheckAuthorizedAuthor
|
||||
from presubmit import CheckStatusFiles
|
||||
|
||||
@ -78,9 +77,6 @@ def _V8PresubmitChecks(input_api, output_api):
|
||||
results.append(output_api.PresubmitError(
|
||||
"Copyright header, trailing whitespaces and two empty lines " \
|
||||
"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()):
|
||||
results.append(output_api.PresubmitError("Status file check failed"))
|
||||
results.extend(CheckAuthorizedAuthor(input_api, output_api))
|
||||
|
@ -7575,7 +7575,7 @@ class V8_EXPORT V8 {
|
||||
/**
|
||||
* Helper class to create a snapshot data blob.
|
||||
*/
|
||||
class SnapshotCreator {
|
||||
class V8_EXPORT SnapshotCreator {
|
||||
public:
|
||||
enum class FunctionCodeHandling { kClear, kKeep };
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace internal {
|
||||
RootIndexMap::RootIndexMap(Isolate* isolate) {
|
||||
map_ = isolate->root_index_map();
|
||||
if (map_ != NULL) return;
|
||||
map_ = new base::HashMap();
|
||||
map_ = new HeapObjectToIndexHashMap();
|
||||
for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) {
|
||||
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
|
||||
Object* root = isolate->heap()->root(root_index);
|
||||
@ -22,12 +22,12 @@ RootIndexMap::RootIndexMap(Isolate* isolate) {
|
||||
// not be referenced through the root list in the snapshot.
|
||||
if (isolate->heap()->RootCanBeTreatedAsConstant(root_index)) {
|
||||
HeapObject* heap_object = HeapObject::cast(root);
|
||||
base::HashMap::Entry* entry = LookupEntry(map_, heap_object, false);
|
||||
if (entry != NULL) {
|
||||
Maybe<uint32_t> maybe_index = map_->Get(heap_object);
|
||||
if (maybe_index.IsJust()) {
|
||||
// Some are initialized to a previous value in the root list.
|
||||
DCHECK_LT(GetValue(entry), i);
|
||||
DCHECK_LT(maybe_index.FromJust(), i);
|
||||
} else {
|
||||
SetValue(LookupEntry(map_, heap_object, true), i);
|
||||
map_->Set(heap_object, i);
|
||||
}
|
||||
} else {
|
||||
// Immortal immovable root objects are constant and allocated on the first
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_ADDRESS_MAP_H_
|
||||
#define V8_ADDRESS_MAP_H_
|
||||
|
||||
#include "include/v8.h"
|
||||
#include "src/assert-scope.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#include "src/objects.h"
|
||||
@ -12,49 +13,52 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class AddressMapBase {
|
||||
protected:
|
||||
static void SetValue(base::HashMap::Entry* entry, uint32_t v) {
|
||||
entry->value = reinterpret_cast<void*>(v);
|
||||
template <typename Type>
|
||||
class PointerToIndexHashMap
|
||||
: public base::TemplateHashMapImpl<uintptr_t, uint32_t,
|
||||
base::KeyEqualityMatcher<intptr_t>,
|
||||
base::DefaultAllocationPolicy> {
|
||||
public:
|
||||
typedef base::TemplateHashMapEntry<uintptr_t, uint32_t> Entry;
|
||||
|
||||
inline void Set(Type value, uint32_t index) {
|
||||
uintptr_t key = Key(value);
|
||||
LookupOrInsert(key, Hash(key))->value = index;
|
||||
}
|
||||
|
||||
static uint32_t GetValue(base::HashMap::Entry* entry) {
|
||||
return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
|
||||
}
|
||||
|
||||
inline static base::HashMap::Entry* LookupEntry(base::HashMap* map,
|
||||
HeapObject* obj,
|
||||
bool insert) {
|
||||
if (insert) {
|
||||
map->LookupOrInsert(Key(obj), Hash(obj));
|
||||
}
|
||||
return map->Lookup(Key(obj), Hash(obj));
|
||||
inline Maybe<uint32_t> Get(Type value) const {
|
||||
uintptr_t key = Key(value);
|
||||
Entry* entry = Lookup(key, Hash(key));
|
||||
if (entry == nullptr) return Nothing<uint32_t>();
|
||||
return Just(entry->value);
|
||||
}
|
||||
|
||||
private:
|
||||
static uint32_t Hash(HeapObject* obj) {
|
||||
return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address()));
|
||||
static uintptr_t Key(Type value) {
|
||||
return reinterpret_cast<uintptr_t>(value);
|
||||
}
|
||||
|
||||
static void* Key(HeapObject* obj) {
|
||||
return reinterpret_cast<void*>(obj->address());
|
||||
static uint32_t Hash(uintptr_t key) {
|
||||
return static_cast<uint32_t>(key >> kPointerSizeLog2);
|
||||
}
|
||||
};
|
||||
|
||||
class RootIndexMap : public AddressMapBase {
|
||||
class AddressToIndexHashMap : public PointerToIndexHashMap<Address> {};
|
||||
class HeapObjectToIndexHashMap : public PointerToIndexHashMap<HeapObject*> {};
|
||||
|
||||
class RootIndexMap {
|
||||
public:
|
||||
explicit RootIndexMap(Isolate* isolate);
|
||||
|
||||
static const int kInvalidRootIndex = -1;
|
||||
|
||||
int Lookup(HeapObject* obj) {
|
||||
base::HashMap::Entry* entry = LookupEntry(map_, obj, false);
|
||||
if (entry) return GetValue(entry);
|
||||
return kInvalidRootIndex;
|
||||
Maybe<uint32_t> maybe_index = map_->Get(obj);
|
||||
return maybe_index.IsJust() ? maybe_index.FromJust() : kInvalidRootIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
base::HashMap* map_;
|
||||
HeapObjectToIndexHashMap* map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RootIndexMap);
|
||||
};
|
||||
@ -186,21 +190,21 @@ class SerializerReference {
|
||||
|
||||
// Mapping objects to their location after deserialization.
|
||||
// This is used during building, but not at runtime by V8.
|
||||
class SerializerReferenceMap : public AddressMapBase {
|
||||
class SerializerReferenceMap {
|
||||
public:
|
||||
SerializerReferenceMap()
|
||||
: no_allocation_(), map_(), attached_reference_index_(0) {}
|
||||
|
||||
SerializerReference Lookup(HeapObject* obj) {
|
||||
base::HashMap::Entry* entry = LookupEntry(&map_, obj, false);
|
||||
return entry ? SerializerReference(GetValue(entry)) : SerializerReference();
|
||||
Maybe<uint32_t> maybe_index = map_.Get(obj);
|
||||
return maybe_index.IsJust() ? SerializerReference(maybe_index.FromJust())
|
||||
: SerializerReference();
|
||||
}
|
||||
|
||||
void Add(HeapObject* obj, SerializerReference b) {
|
||||
DCHECK(b.is_valid());
|
||||
DCHECK_NULL(LookupEntry(&map_, obj, false));
|
||||
base::HashMap::Entry* entry = LookupEntry(&map_, obj, true);
|
||||
SetValue(entry, b.bitfield_);
|
||||
DCHECK(map_.Get(obj).IsNothing());
|
||||
map_.Set(obj, b.bitfield_);
|
||||
}
|
||||
|
||||
SerializerReference AddAttachedReference(HeapObject* attached_reference) {
|
||||
@ -212,7 +216,7 @@ class SerializerReferenceMap : public AddressMapBase {
|
||||
|
||||
private:
|
||||
DisallowHeapAllocation no_allocation_;
|
||||
base::HashMap map_;
|
||||
HeapObjectToIndexHashMap map_;
|
||||
int attached_reference_index_;
|
||||
DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap);
|
||||
};
|
||||
|
@ -1240,7 +1240,6 @@ Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
|
||||
experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
|
||||
v8::Local<Signature> signature, int length) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
DCHECK(!i_isolate->serializer_enabled());
|
||||
LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler);
|
||||
ENTER_V8(i_isolate);
|
||||
return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
|
||||
@ -1251,7 +1250,6 @@ Local<FunctionTemplate> FunctionTemplate::NewWithCache(
|
||||
Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
|
||||
Local<Value> data, Local<Signature> signature, int length) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
DCHECK(!i_isolate->serializer_enabled());
|
||||
LOG_API(i_isolate, FunctionTemplate, NewWithFastHandler);
|
||||
ENTER_V8(i_isolate);
|
||||
return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
|
||||
|
@ -31,10 +31,11 @@ ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) {
|
||||
}
|
||||
|
||||
ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
|
||||
// nullptr is preserved through serialization/deserialization.
|
||||
Add(nullptr, "nullptr");
|
||||
AddReferences(isolate);
|
||||
AddBuiltins(isolate);
|
||||
AddRuntimeFunctions(isolate);
|
||||
AddStatCounters(isolate);
|
||||
AddIsolateAddresses(isolate);
|
||||
AddAccessors(isolate);
|
||||
AddStubCache(isolate);
|
||||
@ -73,8 +74,6 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
|
||||
Add(ExternalReference::isolate_address(isolate).address(), "isolate");
|
||||
Add(ExternalReference::interpreter_dispatch_table_address(isolate).address(),
|
||||
"Interpreter::dispatch_table_address");
|
||||
Add(ExternalReference::interpreter_dispatch_counters(isolate).address(),
|
||||
"Interpreter::interpreter_dispatch_counters");
|
||||
Add(ExternalReference::address_of_negative_infinity().address(),
|
||||
"LDoubleConstant::negative_infinity");
|
||||
Add(ExternalReference::power_double_double_function(isolate).address(),
|
||||
@ -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) {
|
||||
// Top addresses
|
||||
static const char* address_names[] = {
|
||||
|
@ -19,11 +19,9 @@ class ExternalReferenceTable {
|
||||
public:
|
||||
static ExternalReferenceTable* instance(Isolate* isolate);
|
||||
|
||||
int size() const { return refs_.length(); }
|
||||
Address address(int i) { return refs_[i].address; }
|
||||
const char* name(int i) { return refs_[i].name; }
|
||||
|
||||
inline static Address NotAvailable() { return NULL; }
|
||||
uint32_t size() const { return static_cast<uint32_t>(refs_.length()); }
|
||||
Address address(uint32_t i) { return refs_[i].address; }
|
||||
const char* name(uint32_t i) { return refs_[i].name; }
|
||||
|
||||
static const int kDeoptTableSerializeEntryCount = 64;
|
||||
|
||||
@ -43,7 +41,6 @@ class ExternalReferenceTable {
|
||||
void AddReferences(Isolate* isolate);
|
||||
void AddBuiltins(Isolate* isolate);
|
||||
void AddRuntimeFunctions(Isolate* isolate);
|
||||
void AddStatCounters(Isolate* isolate);
|
||||
void AddIsolateAddresses(Isolate* isolate);
|
||||
void AddAccessors(Isolate* isolate);
|
||||
void AddStubCache(Isolate* isolate);
|
||||
|
@ -34,6 +34,7 @@ class RandomNumberGenerator;
|
||||
namespace internal {
|
||||
|
||||
class AccessCompilerData;
|
||||
class AddressToIndexHashMap;
|
||||
class BasicBlockProfiler;
|
||||
class Bootstrapper;
|
||||
class CancelableTaskManager;
|
||||
@ -59,6 +60,7 @@ class ExternalCallbackScope;
|
||||
class ExternalReferenceTable;
|
||||
class Factory;
|
||||
class HandleScopeImplementer;
|
||||
class HeapObjectToIndexHashMap;
|
||||
class HeapProfiler;
|
||||
class HStatistics;
|
||||
class HTracer;
|
||||
@ -400,8 +402,8 @@ typedef List<HeapObject*> DebugObjectCache;
|
||||
V(Object*, string_stream_current_security_token, nullptr) \
|
||||
V(ExternalReferenceTable*, external_reference_table, nullptr) \
|
||||
V(intptr_t*, api_external_references, nullptr) \
|
||||
V(base::HashMap*, external_reference_map, nullptr) \
|
||||
V(base::HashMap*, root_index_map, nullptr) \
|
||||
V(AddressToIndexHashMap*, external_reference_map, nullptr) \
|
||||
V(HeapObjectToIndexHashMap*, root_index_map, nullptr) \
|
||||
V(v8::DeserializeInternalFieldsCallback, \
|
||||
deserialize_internal_fields_callback, nullptr) \
|
||||
V(int, pending_microtask_count, 0) \
|
||||
|
@ -528,7 +528,7 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
int skip = source_.GetInt(); \
|
||||
current = reinterpret_cast<Object**>( \
|
||||
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); \
|
||||
new_object = reinterpret_cast<Object*>(address); \
|
||||
} else if (where == kAttachedReference) { \
|
||||
|
@ -118,6 +118,7 @@ bool PartialSerializer::ShouldBeInThePartialSnapshotCache(HeapObject* o) {
|
||||
DCHECK(!o->IsScript());
|
||||
return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() ||
|
||||
o->IsCode() || o->IsScopeInfo() || o->IsAccessorInfo() ||
|
||||
o->IsTemplateInfo() ||
|
||||
o->map() ==
|
||||
startup_serializer_->isolate()->heap()->fixed_cow_array_map();
|
||||
}
|
||||
|
@ -18,27 +18,24 @@ namespace internal {
|
||||
|
||||
ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
|
||||
map_ = isolate->external_reference_map();
|
||||
if (map_ != NULL) return;
|
||||
map_ = new base::HashMap();
|
||||
if (map_ != nullptr) return;
|
||||
map_ = new AddressToIndexHashMap();
|
||||
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);
|
||||
if (addr == ExternalReferenceTable::NotAvailable()) continue;
|
||||
// We expect no duplicate external references entries in the table.
|
||||
// AccessorRefTable getter may have duplicates, indicated by an empty string
|
||||
// as name.
|
||||
DCHECK(table->name(i)[0] == '\0' ||
|
||||
map_->Lookup(addr, Hash(addr)) == nullptr);
|
||||
map_->LookupOrInsert(addr, Hash(addr))->value = reinterpret_cast<void*>(i);
|
||||
DCHECK(table->name(i)[0] == '\0' || map_->Get(addr).IsNothing());
|
||||
map_->Set(addr, i);
|
||||
DCHECK(map_->Get(addr).IsJust());
|
||||
}
|
||||
isolate->set_external_reference_map(map_);
|
||||
}
|
||||
|
||||
uint32_t ExternalReferenceEncoder::Encode(Address address) const {
|
||||
DCHECK_NOT_NULL(address);
|
||||
base::HashMap::Entry* entry =
|
||||
const_cast<base::HashMap*>(map_)->Lookup(address, Hash(address));
|
||||
if (entry == nullptr) {
|
||||
Maybe<uint32_t> maybe_index = map_->Get(address);
|
||||
if (maybe_index.IsNothing()) {
|
||||
void* function_addr = address;
|
||||
v8::base::OS::PrintError("Unknown external reference %p.\n", function_addr);
|
||||
#ifdef SYMBOLIZE_FUNCTION
|
||||
@ -46,16 +43,15 @@ uint32_t ExternalReferenceEncoder::Encode(Address address) const {
|
||||
#endif // SYMBOLIZE_FUNCTION
|
||||
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,
|
||||
Address address) const {
|
||||
base::HashMap::Entry* entry =
|
||||
const_cast<base::HashMap*>(map_)->Lookup(address, Hash(address));
|
||||
if (entry == NULL) return "<unknown>";
|
||||
uint32_t i = static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
|
||||
return ExternalReferenceTable::instance(isolate)->name(i);
|
||||
Maybe<uint32_t> maybe_index = map_->Get(address);
|
||||
if (maybe_index.IsNothing()) return "<unknown>";
|
||||
return ExternalReferenceTable::instance(isolate)->name(
|
||||
maybe_index.FromJust());
|
||||
}
|
||||
|
||||
void SerializedData::AllocateData(int size) {
|
||||
|
@ -23,12 +23,7 @@ class ExternalReferenceEncoder {
|
||||
const char* NameOfAddress(Isolate* isolate, Address address) const;
|
||||
|
||||
private:
|
||||
static uint32_t Hash(Address key) {
|
||||
return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key) >>
|
||||
kPointerSizeLog2);
|
||||
}
|
||||
|
||||
base::HashMap* map_;
|
||||
AddressToIndexHashMap* map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
|
||||
};
|
||||
|
@ -623,6 +623,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
|
||||
sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
|
||||
sink_->PutInt(skip, "SkipB4ExternalRef");
|
||||
Address target = rinfo->target_external_reference();
|
||||
DCHECK_NOT_NULL(target); // Code does not reference null.
|
||||
sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
|
||||
bytes_processed_so_far_ += rinfo->target_address_size();
|
||||
}
|
||||
|
@ -30,25 +30,26 @@ class StartupSerializer : public Serializer {
|
||||
int PartialSnapshotCacheIndex(HeapObject* o);
|
||||
|
||||
private:
|
||||
class PartialCacheIndexMap : public AddressMapBase {
|
||||
class PartialCacheIndexMap {
|
||||
public:
|
||||
PartialCacheIndexMap() : map_(), next_index_(0) {}
|
||||
|
||||
// Lookup object in the map. Return its index if found, or create
|
||||
// a new entry with new_index as value, and return kInvalidIndex.
|
||||
bool LookupOrInsert(HeapObject* obj, int* index_out) {
|
||||
base::HashMap::Entry* entry = LookupEntry(&map_, obj, false);
|
||||
if (entry != NULL) {
|
||||
*index_out = GetValue(entry);
|
||||
Maybe<uint32_t> maybe_index = map_.Get(obj);
|
||||
if (maybe_index.IsJust()) {
|
||||
*index_out = maybe_index.FromJust();
|
||||
return true;
|
||||
}
|
||||
*index_out = next_index_;
|
||||
SetValue(LookupEntry(&map_, obj, true), next_index_++);
|
||||
map_.Set(obj, next_index_++);
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
base::HashMap map_;
|
||||
DisallowHeapAllocation no_allocation_;
|
||||
HeapObjectToIndexHashMap map_;
|
||||
int next_index_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PartialCacheIndexMap);
|
||||
|
@ -2022,11 +2022,15 @@ void SerializedCallbackReplacement(
|
||||
args.GetReturnValue().Set(v8_num(1337));
|
||||
}
|
||||
|
||||
static int serialized_static_field = 314;
|
||||
|
||||
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[] = {
|
||||
reinterpret_cast<intptr_t>(SerializedCallbackReplacement), 0};
|
||||
reinterpret_cast<intptr_t>(SerializedCallbackReplacement),
|
||||
reinterpret_cast<intptr_t>(&serialized_static_field), 0};
|
||||
|
||||
TEST(SnapshotCreatorExternalReferences) {
|
||||
DisableAlwaysOpt();
|
||||
@ -2142,7 +2146,6 @@ TEST(SnapshotCreatorTemplates) {
|
||||
InternalFieldData* a1 = new InternalFieldData{11};
|
||||
InternalFieldData* b0 = new InternalFieldData{20};
|
||||
InternalFieldData* c0 = new InternalFieldData{30};
|
||||
InternalFieldData* c1 = new InternalFieldData{31};
|
||||
|
||||
v8::SnapshotCreator creator(original_external_references);
|
||||
v8::Isolate* isolate = creator.GetIsolate();
|
||||
@ -2158,7 +2161,7 @@ TEST(SnapshotCreatorTemplates) {
|
||||
v8::Context::New(isolate, no_extension, global_template);
|
||||
v8::Local<v8::ObjectTemplate> object_template =
|
||||
v8::ObjectTemplate::New(isolate);
|
||||
object_template->SetInternalFieldCount(2);
|
||||
object_template->SetInternalFieldCount(3);
|
||||
|
||||
v8::Context::Scope context_scope(context);
|
||||
ExpectInt32("f()", 42);
|
||||
@ -2169,12 +2172,17 @@ TEST(SnapshotCreatorTemplates) {
|
||||
object_template->NewInstance(context).ToLocalChecked();
|
||||
v8::Local<v8::Object> c =
|
||||
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->SetAlignedPointerInInternalField(1, a1);
|
||||
b->SetAlignedPointerInInternalField(0, b0);
|
||||
b->SetInternalField(1, c);
|
||||
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_EQ(0u, creator.AddContext(context));
|
||||
@ -2186,7 +2194,6 @@ TEST(SnapshotCreatorTemplates) {
|
||||
|
||||
delete a1;
|
||||
delete b0;
|
||||
delete c1;
|
||||
delete c0;
|
||||
}
|
||||
|
||||
@ -2239,19 +2246,28 @@ TEST(SnapshotCreatorTemplates) {
|
||||
a->GetInternalField(0)->ToObject(context).ToLocalChecked();
|
||||
InternalFieldData* a1 = reinterpret_cast<InternalFieldData*>(
|
||||
a->GetAlignedPointerFromInternalField(1));
|
||||
v8::Local<v8::Value> a2 = a->GetInternalField(2);
|
||||
|
||||
InternalFieldData* b0 = reinterpret_cast<InternalFieldData*>(
|
||||
b->GetAlignedPointerFromInternalField(0));
|
||||
v8::Local<v8::Object> c =
|
||||
b->GetInternalField(1)->ToObject(context).ToLocalChecked();
|
||||
v8::Local<v8::Value> b2 = b->GetInternalField(2);
|
||||
|
||||
InternalFieldData* c0 = reinterpret_cast<InternalFieldData*>(
|
||||
c->GetAlignedPointerFromInternalField(0));
|
||||
InternalFieldData* c1 = reinterpret_cast<InternalFieldData*>(
|
||||
c->GetAlignedPointerFromInternalField(1));
|
||||
v8::Local<v8::Value> c1 = c->GetInternalField(1);
|
||||
v8::Local<v8::Value> c2 = c->GetInternalField(2);
|
||||
|
||||
CHECK_EQ(11u, a1->data);
|
||||
CHECK(a2->IsUndefined());
|
||||
CHECK_EQ(20u, b0->data);
|
||||
CHECK(b2->IsUndefined());
|
||||
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.
|
||||
CHECK(v8::ObjectTemplate::FromSnapshot(isolate, 2).IsEmpty());
|
||||
@ -2260,7 +2276,6 @@ TEST(SnapshotCreatorTemplates) {
|
||||
|
||||
delete a1;
|
||||
delete b0;
|
||||
delete c1;
|
||||
delete c0;
|
||||
}
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
#!/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):
|
||||
print "Total violating files: %s" % violations
|
||||
return success
|
||||
|
||||
|
||||
def CheckExternalReferenceRegistration(workspace):
|
||||
code = subprocess.call(
|
||||
[sys.executable, join(workspace, "tools", "external-reference-check.py")])
|
||||
return code == 0
|
||||
|
||||
|
||||
def _CheckStatusFileForDuplicateKeys(filepath):
|
||||
comma_space_bracket = re.compile(", *]")
|
||||
lines = []
|
||||
@ -503,7 +496,6 @@ def Main():
|
||||
print "Running copyright header, trailing whitespaces and " \
|
||||
"two empty lines between declarations check..."
|
||||
success &= SourceProcessor().Run(workspace)
|
||||
success &= CheckExternalReferenceRegistration(workspace)
|
||||
success &= CheckStatusFiles(workspace)
|
||||
if success:
|
||||
return 0
|
||||
|
Loading…
Reference in New Issue
Block a user