mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:09:49 +00:00
[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:
parent
1a56d6534c
commit
3b057dea98
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -46,7 +46,6 @@ enum {
|
|||
|
||||
kExtractorParameterTypes,
|
||||
kExtractorParameterNames,
|
||||
kEmptyContextObject,
|
||||
kEmptyContextScopeObject,
|
||||
kImplicitClosureScopeObject,
|
||||
kEmptyObjectPool,
|
||||
|
|
Loading…
Reference in a new issue