Encode any deoptimizer entry in serialized data.
This removes kDeoptTableSerializeEntryCount heuristic constant. Review-Url: https://codereview.chromium.org/2790573002 Cr-Commit-Position: refs/heads/master@{#44379}
This commit is contained in:
parent
21f064fcdc
commit
ddb67ec9da
@ -45,7 +45,6 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
|
||||
AddIsolateAddresses(isolate);
|
||||
AddAccessors(isolate);
|
||||
AddStubCache(isolate);
|
||||
AddDeoptEntries(isolate);
|
||||
// API references must be added last.
|
||||
AddApiReferences(isolate);
|
||||
}
|
||||
@ -436,19 +435,6 @@ void ExternalReferenceTable::AddStubCache(Isolate* isolate) {
|
||||
"Store StubCache::secondary_->map");
|
||||
}
|
||||
|
||||
void ExternalReferenceTable::AddDeoptEntries(Isolate* isolate) {
|
||||
// Add a small set of deopt entry addresses to encoder without generating
|
||||
// the
|
||||
// deopt table code, which isn't possible at deserialization time.
|
||||
HandleScope scope(isolate);
|
||||
for (int entry = 0; entry < kDeoptTableSerializeEntryCount; ++entry) {
|
||||
Address address = Deoptimizer::GetDeoptimizationEntry(
|
||||
isolate, entry, Deoptimizer::LAZY,
|
||||
Deoptimizer::CALCULATE_ENTRY_ADDRESS);
|
||||
Add(address, "lazy_deopt");
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalReferenceTable::AddApiReferences(Isolate* isolate) {
|
||||
// Add external references provided by the embedder (a null-terminated
|
||||
// array).
|
||||
|
@ -34,8 +34,6 @@ class ExternalReferenceTable {
|
||||
|
||||
static const char* ResolveSymbol(void* address);
|
||||
|
||||
static const int kDeoptTableSerializeEntryCount = 64;
|
||||
|
||||
private:
|
||||
struct ExternalReferenceEntry {
|
||||
Address address;
|
||||
@ -62,7 +60,6 @@ class ExternalReferenceTable {
|
||||
void AddIsolateAddresses(Isolate* isolate);
|
||||
void AddAccessors(Isolate* isolate);
|
||||
void AddStubCache(Isolate* isolate);
|
||||
void AddDeoptEntries(Isolate* isolate);
|
||||
void AddApiReferences(Isolate* isolate);
|
||||
|
||||
List<ExternalReferenceEntry> refs_;
|
||||
|
@ -2731,16 +2731,6 @@ bool Isolate::Init(Deserializer* des) {
|
||||
ast_string_constants_ = new AstStringConstants(this, heap()->HashSeed());
|
||||
}
|
||||
|
||||
if (!create_heap_objects) {
|
||||
// Now that the heap is consistent, it's OK to generate the code for the
|
||||
// deopt entry table that might have been referred to by optimized code in
|
||||
// the snapshot.
|
||||
HandleScope scope(this);
|
||||
Deoptimizer::EnsureCodeForDeoptimizationEntry(
|
||||
this, Deoptimizer::LAZY,
|
||||
ExternalReferenceTable::kDeoptTableSerializeEntryCount - 1);
|
||||
}
|
||||
|
||||
if (!serializer_enabled()) {
|
||||
// Ensure that all stubs which need to be generated ahead of time, but
|
||||
// cannot be serialized into the snapshot have been generated.
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/api.h"
|
||||
#include "src/assembler-inl.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/deoptimizer.h"
|
||||
#include "src/external-reference-table.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/isolate.h"
|
||||
@ -732,6 +733,33 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
break;
|
||||
}
|
||||
|
||||
case kDeoptimizerEntryFromCode:
|
||||
case kDeoptimizerEntryPlain: {
|
||||
int skip = source_.GetInt();
|
||||
current = reinterpret_cast<Object**>(
|
||||
reinterpret_cast<intptr_t>(current) + skip);
|
||||
Deoptimizer::BailoutType bailout_type =
|
||||
static_cast<Deoptimizer::BailoutType>(source_.Get());
|
||||
int entry_id = source_.GetInt();
|
||||
HandleScope scope(isolate);
|
||||
Address address = Deoptimizer::GetDeoptimizationEntry(
|
||||
isolate_, entry_id, bailout_type, Deoptimizer::ENSURE_ENTRY_CODE);
|
||||
if (data == kDeoptimizerEntryFromCode) {
|
||||
Address location_of_branch_data = reinterpret_cast<Address>(current);
|
||||
Assembler::deserialization_set_special_target_at(
|
||||
isolate, location_of_branch_data,
|
||||
Code::cast(HeapObject::FromAddress(current_object_address)),
|
||||
address);
|
||||
location_of_branch_data += Assembler::kSpecialTargetSize;
|
||||
current = reinterpret_cast<Object**>(location_of_branch_data);
|
||||
} else {
|
||||
Object* new_object = reinterpret_cast<Object*>(address);
|
||||
UnalignedCopy(current, &new_object);
|
||||
current++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kInternalReferenceEncoded:
|
||||
case kInternalReference: {
|
||||
// Internal reference address is not encoded via skip, but by offset
|
||||
|
@ -184,7 +184,10 @@ class SerializerDeserializer : public ObjectVisitor {
|
||||
static const int kHotObjectWithSkip = 0x58;
|
||||
static const int kHotObjectMask = 0x07;
|
||||
|
||||
// 0x35..0x37, 0x55..0x57, 0x75..0x7f unused.
|
||||
static const int kDeoptimizerEntryPlain = 0x35;
|
||||
static const int kDeoptimizerEntryFromCode = 0x36;
|
||||
|
||||
// 0x37, 0x55..0x57, 0x75..0x7f unused.
|
||||
|
||||
// ---------- byte code range 0x80..0xff ----------
|
||||
// First 32 root array items.
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/snapshot/serializer.h"
|
||||
|
||||
#include "src/assembler-inl.h"
|
||||
#include "src/deoptimizer.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/snapshot/natives.h"
|
||||
@ -334,6 +335,25 @@ bool Serializer::HasNotExceededFirstPageOfEachSpace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::ObjectSerializer::TryEncodeDeoptimizationEntry(
|
||||
HowToCode how_to_code, Address target, int skip) {
|
||||
for (int bailout_type = 0; bailout_type <= Deoptimizer::kLastBailoutType;
|
||||
++bailout_type) {
|
||||
int id = Deoptimizer::GetDeoptimizationId(
|
||||
serializer_->isolate(), target,
|
||||
static_cast<Deoptimizer::BailoutType>(bailout_type));
|
||||
if (id == Deoptimizer::kNotDeoptimizationEntry) continue;
|
||||
sink_->Put(how_to_code == kPlain ? kDeoptimizerEntryPlain
|
||||
: kDeoptimizerEntryFromCode,
|
||||
"DeoptimizationEntry");
|
||||
sink_->PutInt(skip, "SkipB4DeoptimizationEntry");
|
||||
sink_->Put(bailout_type, "BailoutType");
|
||||
sink_->PutInt(id, "EntryId");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
|
||||
int size, Map* map) {
|
||||
if (serializer_->code_address_map_) {
|
||||
@ -611,10 +631,12 @@ void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) {
|
||||
void Serializer::ObjectSerializer::VisitExternalReference(Address* p) {
|
||||
int skip = OutputRawData(reinterpret_cast<Address>(p),
|
||||
kCanReturnSkipInsteadOfSkipping);
|
||||
Address target = *p;
|
||||
if (!TryEncodeDeoptimizationEntry(kPlain, target, skip)) {
|
||||
sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef");
|
||||
sink_->PutInt(skip, "SkipB4ExternalRef");
|
||||
Address target = *p;
|
||||
sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
|
||||
}
|
||||
bytes_processed_so_far_ += kPointerSize;
|
||||
}
|
||||
|
||||
@ -622,11 +644,14 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
|
||||
int skip = OutputRawData(rinfo->target_address_address(),
|
||||
kCanReturnSkipInsteadOfSkipping);
|
||||
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
|
||||
sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
|
||||
sink_->PutInt(skip, "SkipB4ExternalRef");
|
||||
Address target = rinfo->target_external_reference();
|
||||
if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) {
|
||||
sink_->Put(kExternalReference + how_to_code + kStartOfObject,
|
||||
"ExternalRef");
|
||||
sink_->PutInt(skip, "SkipB4ExternalRef");
|
||||
DCHECK_NOT_NULL(target); // Code does not reference null.
|
||||
sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
|
||||
}
|
||||
bytes_processed_so_far_ += rinfo->target_address_size();
|
||||
}
|
||||
|
||||
@ -658,10 +683,13 @@ void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
|
||||
int skip = OutputRawData(rinfo->target_address_address(),
|
||||
kCanReturnSkipInsteadOfSkipping);
|
||||
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
|
||||
sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
|
||||
sink_->PutInt(skip, "SkipB4ExternalRef");
|
||||
Address target = rinfo->target_address();
|
||||
if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) {
|
||||
sink_->Put(kExternalReference + how_to_code + kStartOfObject,
|
||||
"ExternalRef");
|
||||
sink_->PutInt(skip, "SkipB4ExternalRef");
|
||||
sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
|
||||
}
|
||||
bytes_processed_so_far_ += rinfo->target_address_size();
|
||||
}
|
||||
|
||||
|
@ -300,6 +300,8 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
|
||||
}
|
||||
|
||||
private:
|
||||
bool TryEncodeDeoptimizationEntry(HowToCode how_to_code, Address target,
|
||||
int skip);
|
||||
void SerializePrologue(AllocationSpace space, int size, Map* map);
|
||||
|
||||
bool SerializeExternalNativeSourceString(
|
||||
|
Loading…
Reference in New Issue
Block a user