[VM] Remove legacy Object::empty_context() and CTX constant

Our generated code does not keep the context in a special register
anymore (for quite some time now).  The context is just another definition
in the IR language and gets assigned register locations by the linearscan
register allocator.

Furthermore we no longer use an empty context for closures which have no
captured states, instead the context of those closures is just `null`.

This CL therefore removes Object::empty_context() and the CTX constant.

Change-Id: Iea171e0d0fd56c48f1c456e08e060a12267e39cc
Reviewed-on: https://dart-review.googlesource.com/51129
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Martin Kustermann 2018-04-19 20:09:38 +00:00 committed by commit-bot@chromium.org
parent 1a56d6534c
commit 3b057dea98
18 changed files with 40 additions and 73 deletions

View file

@ -199,7 +199,7 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 10) {
#if defined(DEBUG)
Context& ctx = Context::Handle();
ctx = Closure::Cast(closure).context();
ASSERT(ctx.num_variables() == 0);
ASSERT(ctx.IsNull());
#endif
// Get the parent function so that we get the right function name.
func = func.parent_function();

View file

@ -5069,7 +5069,6 @@ void Serializer::AddVMIsolateBaseObjects() {
AddBaseObject(Object::extractor_parameter_types().raw());
ASSERT(Object::extractor_parameter_names().raw() != Object::null());
AddBaseObject(Object::extractor_parameter_names().raw());
AddBaseObject(Object::empty_context().raw());
AddBaseObject(Object::empty_context_scope().raw());
AddBaseObject(Object::empty_descriptors().raw());
AddBaseObject(Object::empty_var_descriptors().raw());
@ -5515,7 +5514,6 @@ void Deserializer::AddVMIsolateBaseObjects() {
AddBaseObject(Object::extractor_parameter_types().raw());
ASSERT(Object::extractor_parameter_names().raw() != Object::null());
AddBaseObject(Object::extractor_parameter_names().raw());
AddBaseObject(Object::empty_context().raw());
AddBaseObject(Object::empty_context_scope().raw());
AddBaseObject(Object::empty_descriptors().raw());
AddBaseObject(Object::empty_var_descriptors().raw());

View file

@ -2898,21 +2898,21 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
__ LoadFromOffset(kWord, CTX, FP, closure_parameter->index() * kWordSize);
__ LoadFieldFromOffset(kWord, CTX, CTX, Closure::context_offset());
__ LoadFromOffset(kWord, R6, FP, closure_parameter->index() * kWordSize);
__ LoadFieldFromOffset(kWord, R6, R6, Closure::context_offset());
const intptr_t context_index =
parsed_function.current_context_var()->index();
__ StoreToOffset(kWord, CTX, FP, context_index * kWordSize);
__ StoreToOffset(kWord, R6, FP, context_index * kWordSize);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
__ StoreIntoObjectOffset(CTX,
__ StoreIntoObjectOffset(R6,
Context::variable_offset(exception_var().index()),
kExceptionObjectReg);
__ StoreIntoObjectOffset(CTX,
__ StoreIntoObjectOffset(R6,
Context::variable_offset(stacktrace_var().index()),
kStackTraceObjectReg);
} else {

View file

@ -2647,21 +2647,21 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
__ LoadFromOffset(CTX, FP, closure_parameter->index() * kWordSize);
__ LoadFieldFromOffset(CTX, CTX, Closure::context_offset());
__ LoadFromOffset(R28, FP, closure_parameter->index() * kWordSize);
__ LoadFieldFromOffset(R28, R28, Closure::context_offset());
const intptr_t context_index =
parsed_function.current_context_var()->index();
__ StoreToOffset(CTX, FP, context_index * kWordSize);
__ StoreToOffset(R28, FP, context_index * kWordSize);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
__ StoreIntoObjectOffset(CTX,
__ StoreIntoObjectOffset(R28,
Context::variable_offset(exception_var().index()),
kExceptionObjectReg);
__ StoreIntoObjectOffset(CTX,
__ StoreIntoObjectOffset(R28,
Context::variable_offset(stacktrace_var().index()),
kStackTraceObjectReg);
} else {

View file

@ -2506,12 +2506,12 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
__ movl(CTX, Address(EBP, closure_parameter->index() * kWordSize));
__ movl(CTX, FieldAddress(CTX, Closure::context_offset()));
__ movl(EDI, Address(EBP, closure_parameter->index() * kWordSize));
__ movl(EDI, FieldAddress(EDI, Closure::context_offset()));
#ifdef DEBUG
Label ok;
__ LoadClassId(EBX, CTX);
__ LoadClassId(EBX, EDI);
__ cmpl(EBX, Immediate(kContextCid));
__ j(EQUAL, &ok, Assembler::kNearJump);
__ Stop("Incorrect context at entry");
@ -2520,19 +2520,19 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const intptr_t context_index =
parsed_function.current_context_var()->index();
__ movl(Address(EBP, context_index * kWordSize), CTX);
__ movl(Address(EBP, context_index * kWordSize), EDI);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
__ StoreIntoObject(
CTX,
FieldAddress(CTX, Context::variable_offset(exception_var().index())),
EDI,
FieldAddress(EDI, Context::variable_offset(exception_var().index())),
kExceptionObjectReg);
__ StoreIntoObject(
CTX,
FieldAddress(CTX, Context::variable_offset(stacktrace_var().index())),
EDI,
FieldAddress(EDI, Context::variable_offset(stacktrace_var().index())),
kStackTraceObjectReg);
} else {
// Restore stack and initialize the two exception variables:

View file

@ -2581,12 +2581,12 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
__ movq(CTX, Address(RBP, closure_parameter->index() * kWordSize));
__ movq(CTX, FieldAddress(CTX, Closure::context_offset()));
__ movq(R12, Address(RBP, closure_parameter->index() * kWordSize));
__ movq(R12, FieldAddress(R12, Closure::context_offset()));
#ifdef DEBUG
Label ok;
__ LoadClassId(RBX, CTX);
__ LoadClassId(RBX, R12);
__ cmpq(RBX, Immediate(kContextCid));
__ j(EQUAL, &ok, Assembler::kNearJump);
__ Stop("Incorrect context at entry");
@ -2595,19 +2595,19 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const intptr_t context_index =
parsed_function.current_context_var()->index();
__ movq(Address(RBP, context_index * kWordSize), CTX);
__ movq(Address(RBP, context_index * kWordSize), R12);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
__ StoreIntoObject(
CTX,
FieldAddress(CTX, Context::variable_offset(exception_var().index())),
R12,
FieldAddress(R12, Context::variable_offset(exception_var().index())),
kExceptionObjectReg);
__ StoreIntoObject(
CTX,
FieldAddress(CTX, Context::variable_offset(stacktrace_var().index())),
R12,
FieldAddress(R12, Context::variable_offset(stacktrace_var().index())),
kStackTraceObjectReg);
} else {
__ movq(Address(RBP, exception_var().index() * kWordSize),

View file

@ -65,7 +65,7 @@ enum Register {
R3 = 3,
R4 = 4,
R5 = 5, // PP
R6 = 6, // CTX
R6 = 6,
R7 = 7, // iOS FP
R8 = 8,
R9 = 9,
@ -264,7 +264,6 @@ const FpuRegister kNoFpuRegister = kNoQRegister;
// Register aliases.
const Register TMP = IP; // Used as scratch register by assembler.
const Register TMP2 = kNoRegister; // There is no second assembler temporary.
const Register CTX = R6; // Location of current context at method entry.
const Register PP = R5; // Caches object pool pointer in generated code.
const Register SPREG = SP; // Stack pointer register.
const Register FPREG = FP; // Frame pointer register.

View file

@ -38,7 +38,7 @@ enum Register {
R25 = 25,
R26 = 26, // THR
R27 = 27, // PP
R28 = 28, // CTX
R28 = 28,
R29 = 29, // FP
R30 = 30, // LR
R31 = 31, // ZR, CSP
@ -107,7 +107,6 @@ const FpuRegister kNoFpuRegister = kNoVRegister;
// Register aliases.
const Register TMP = R16; // Used as scratch register by assembler.
const Register TMP2 = R17;
const Register CTX = R28; // Location of current context at method entry.
const Register PP = R27; // Caches object pool pointer in generated code.
const Register CODE_REG = R24;
const Register FPREG = FP; // Frame pointer register.
@ -151,12 +150,12 @@ const VRegister kAbiFirstPreservedFpuReg = V8;
const VRegister kAbiLastPreservedFpuReg = V15;
const int kAbiPreservedFpuRegCount = 8;
const intptr_t kReservedCpuRegisters =
(1 << SPREG) | // Dart SP
(1 << FPREG) | (1 << TMP) | (1 << TMP2) | (1 << PP) | (1 << THR) |
(1 << LR) | (1 << R31) | // C++ SP
(1 << CTX) | (1 << R18); // iOS platform register.
// TODO(rmacnak): Only reserve on Mac & iOS.
const intptr_t kReservedCpuRegisters = (1 << SPREG) | // Dart SP
(1 << FPREG) | (1 << TMP) | (1 << TMP2) |
(1 << PP) | (1 << THR) | (1 << LR) |
(1 << R31) | // C++ SP
(1 << R18); // iOS platform register.
// TODO(rmacnak): Only reserve on Mac & iOS.
// CPU registers available to Dart allocator.
const RegList kDartAvailableCpuRegs =
kAllCpuRegistersList & ~kReservedCpuRegisters;

View file

@ -1080,7 +1080,6 @@ const intptr_t ARGS_DESC_REG = 0;
const intptr_t CODE_REG = 0;
const intptr_t kExceptionObjectReg = 0;
const intptr_t kStackTraceObjectReg = 0;
const intptr_t CTX = 0;
enum FpuRegister {
kNoFpuRegister = -1,

View file

@ -56,7 +56,6 @@ const FpuRegister kNoFpuRegister = kNoXmmRegister;
// Register aliases.
const Register TMP = kNoRegister; // No scratch register used by assembler.
const Register TMP2 = kNoRegister; // No second assembler scratch register.
const Register CTX = EDI; // Location of current context at method entry.
const Register CODE_REG = EDI;
const Register PP = kNoRegister; // No object pool pointer.
const Register SPREG = ESP; // Stack pointer register.

View file

@ -99,7 +99,6 @@ enum RexBits {
// Register aliases.
const Register TMP = R11; // Used as scratch register by the assembler.
const Register TMP2 = kNoRegister; // No second assembler scratch register.
const Register CTX = R12; // Location of current context at method entry.
// Caches object pool pointer in generated code.
const Register PP = R15;
const Register SPREG = RSP; // Stack pointer register.

View file

@ -113,7 +113,6 @@ TypeArguments* Object::null_type_arguments_ = NULL;
TypeArguments* Object::empty_type_arguments_ = NULL;
Array* Object::empty_array_ = NULL;
Array* Object::zero_array_ = NULL;
Context* Object::empty_context_ = NULL;
ContextScope* Object::empty_context_scope_ = NULL;
ObjectPool* Object::empty_object_pool_ = NULL;
PcDescriptors* Object::empty_descriptors_ = NULL;
@ -510,7 +509,6 @@ void Object::InitOnce(Isolate* isolate) {
empty_type_arguments_ = TypeArguments::ReadOnlyHandle();
empty_array_ = Array::ReadOnlyHandle();
zero_array_ = Array::ReadOnlyHandle();
empty_context_ = Context::ReadOnlyHandle();
empty_context_scope_ = ContextScope::ReadOnlyHandle();
empty_object_pool_ = ObjectPool::ReadOnlyHandle();
empty_descriptors_ = PcDescriptors::ReadOnlyHandle();
@ -778,17 +776,6 @@ void Object::InitOnce(Isolate* isolate) {
zero_array_->SetCanonical();
}
// Allocate and initialize the empty context object.
{
uword address = heap->Allocate(Context::InstanceSize(0), Heap::kOld);
InitializeObject(address, kContextCid, Context::InstanceSize(0), true);
Context::initializeHandle(empty_context_, reinterpret_cast<RawContext*>(
address + kHeapObjectTag));
empty_context_->StoreNonPointer(&empty_context_->raw_ptr()->num_variables_,
0);
empty_context_->SetCanonical();
}
// Allocate and initialize the canonical empty context scope object.
{
uword address = heap->Allocate(ContextScope::InstanceSize(0), Heap::kOld);
@ -980,8 +967,6 @@ void Object::InitOnce(Isolate* isolate) {
ASSERT(empty_array_->IsArray());
ASSERT(!zero_array_->IsSmi());
ASSERT(zero_array_->IsArray());
ASSERT(!empty_context_->IsSmi());
ASSERT(empty_context_->IsContext());
ASSERT(!empty_context_scope_->IsSmi());
ASSERT(empty_context_scope_->IsContextScope());
ASSERT(!empty_descriptors_->IsSmi());
@ -7643,7 +7628,7 @@ RawInstance* Function::ImplicitStaticClosure() const {
ASSERT(IsImplicitStaticClosureFunction());
if (implicit_static_closure() == Instance::null()) {
Zone* zone = Thread::Current()->zone();
const Context& context = Object::empty_context();
const Context& context = Context::Handle(zone);
Instance& closure =
Instance::Handle(zone, Closure::New(Object::null_type_arguments(),
Object::null_type_arguments(),

View file

@ -384,11 +384,6 @@ class Object {
return *zero_array_;
}
static const Context& empty_context() {
ASSERT(empty_context_ != NULL);
return *empty_context_;
}
static const ContextScope& empty_context_scope() {
ASSERT(empty_context_scope_ != NULL);
return *empty_context_scope_;
@ -824,7 +819,6 @@ class Object {
static TypeArguments* empty_type_arguments_;
static Array* empty_array_;
static Array* zero_array_;
static Context* empty_context_;
static ContextScope* empty_context_scope_;
static ObjectPool* empty_object_pool_;
static PcDescriptors* empty_descriptors_;

View file

@ -1478,9 +1478,7 @@ RawContext* Context::ReadFrom(SnapshotReader* reader,
int32_t num_vars = reader->Read<int32_t>();
Context& context = Context::ZoneHandle(reader->zone());
reader->AddBackRef(object_id, &context, kIsDeserialized);
if (num_vars == 0) {
context ^= Object::empty_context().raw();
} else {
if (num_vars != 0) {
context ^= Context::New(num_vars);
// Set all the object fields.

View file

@ -133,7 +133,7 @@ static Register LookupCpuRegisterByName(const char* name) {
"sp", "ip", "fp", "pp", "ctx"};
static const Register kRegisters[] = {R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, R13, R14, R15,
PC, LR, SP, IP, FP, PP, CTX};
PC, LR, SP, IP, FP, PP};
ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
if (strcmp(kNames[i], name) == 0) {

View file

@ -133,14 +133,14 @@ static Register LookupCpuRegisterByName(const char* name) {
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30",
"ip0", "ip1", "pp", "ctx", "fp", "lr", "sp", "zr",
"ip0", "ip1", "pp", "fp", "lr", "sp", "zr",
};
static const Register kRegisters[] = {
R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
R22, R23, R24, R25, R26, R27, R28, R29, R30,
IP0, IP1, PP, CTX, FP, LR, R31, ZR,
IP0, IP1, PP, FP, LR, R31, ZR,
};
ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {

View file

@ -759,7 +759,6 @@ RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
Object::extractor_parameter_types().raw());
READ_VM_SINGLETON_OBJ(kExtractorParameterNames,
Object::extractor_parameter_names().raw());
READ_VM_SINGLETON_OBJ(kEmptyContextObject, Object::empty_context().raw());
READ_VM_SINGLETON_OBJ(kEmptyContextScopeObject,
Object::empty_context_scope().raw());
READ_VM_SINGLETON_OBJ(kEmptyObjectPool, Object::empty_object_pool().raw());
@ -1028,7 +1027,6 @@ bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
kExtractorParameterTypes);
WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_names().raw(),
kExtractorParameterNames);
WRITE_VM_SINGLETON_OBJ(Object::empty_context().raw(), kEmptyContextObject);
WRITE_VM_SINGLETON_OBJ(Object::empty_context_scope().raw(),
kEmptyContextScopeObject);
WRITE_VM_SINGLETON_OBJ(Object::empty_object_pool().raw(), kEmptyObjectPool);

View file

@ -46,7 +46,6 @@ enum {
kExtractorParameterTypes,
kExtractorParameterNames,
kEmptyContextObject,
kEmptyContextScopeObject,
kImplicitClosureScopeObject,
kEmptyObjectPool,