Move vm_tags from isolate to thread, since we may have multiple threads in same isolate (GC, background compilation)
BUG= R=johnmccutchan@google.com, rmacnak@google.com Review URL: https://codereview.chromium.org/1387643002 .
This commit is contained in:
@@ -787,6 +787,10 @@ class Assembler : public ValueObject {
|
||||
Register array,
|
||||
Register index);
|
||||
|
||||
static Address VMTagAddress() {
|
||||
return Address(THR, Thread::vm_tag_offset());
|
||||
}
|
||||
|
||||
/*
|
||||
* Misc. functionality
|
||||
*/
|
||||
|
||||
@@ -1593,6 +1593,10 @@ class Assembler : public ValueObject {
|
||||
Register array,
|
||||
Register index);
|
||||
|
||||
static Address VMTagAddress() {
|
||||
return Address(THR, Thread::vm_tag_offset());
|
||||
}
|
||||
|
||||
// On some other platforms, we draw a distinction between safe and unsafe
|
||||
// smis.
|
||||
static bool IsSafe(const Object& object) { return true; }
|
||||
|
||||
@@ -1032,6 +1032,10 @@ class Assembler : public ValueObject {
|
||||
Register array,
|
||||
Register index);
|
||||
|
||||
static Address VMTagAddress() {
|
||||
return Address(THR, Thread::vm_tag_offset());
|
||||
}
|
||||
|
||||
// On some other platforms, we draw a distinction between safe and unsafe
|
||||
// smis.
|
||||
static bool IsSafe(const Object& object) { return true; }
|
||||
|
||||
@@ -771,7 +771,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
||||
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
|
||||
reusable_handles_() {
|
||||
flags_.CopyFrom(api_flags);
|
||||
set_vm_tag(VMTag::kEmbedderTagId);
|
||||
Thread::Current()->set_vm_tag(VMTag::kEmbedderTagId);
|
||||
set_user_tag(UserTags::kDefaultUserTag);
|
||||
}
|
||||
|
||||
@@ -1945,7 +1945,8 @@ intptr_t Isolate::ProfileInterrupt() {
|
||||
|
||||
|
||||
void Isolate::ProfileIdle() {
|
||||
vm_tag_counters_.Increment(vm_tag());
|
||||
// Currently we are only sampling the mutator thread.
|
||||
vm_tag_counters_.Increment(VMTag::kIdleTagId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -239,16 +239,6 @@ class Isolate : public BaseIsolate {
|
||||
mutator_thread_->set_top_exit_frame_info(value);
|
||||
}
|
||||
|
||||
uword vm_tag() const {
|
||||
return vm_tag_;
|
||||
}
|
||||
void set_vm_tag(uword tag) {
|
||||
vm_tag_ = tag;
|
||||
}
|
||||
static intptr_t vm_tag_offset() {
|
||||
return OFFSET_OF(Isolate, vm_tag_);
|
||||
}
|
||||
|
||||
ApiState* api_state() const { return api_state_; }
|
||||
void set_api_state(ApiState* value) { api_state_ = value; }
|
||||
|
||||
|
||||
@@ -1843,7 +1843,7 @@ RawObject* Object::Allocate(intptr_t cls_id,
|
||||
}
|
||||
const Class& cls = Class::Handle(class_table->At(cls_id));
|
||||
if (cls.TraceAllocation(isolate)) {
|
||||
Profiler::RecordAllocation(isolate, cls_id);
|
||||
Profiler::RecordAllocation(thread, cls_id);
|
||||
}
|
||||
NoSafepointScope no_safepoint;
|
||||
InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate()));
|
||||
|
||||
+32
-26
@@ -165,7 +165,7 @@ void Profiler::BeginExecution(Isolate* isolate) {
|
||||
return;
|
||||
}
|
||||
Thread* thread = Thread::Current();
|
||||
thread->SetThreadInterrupter(RecordSampleInterruptCallback, isolate);
|
||||
thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread);
|
||||
ThreadInterrupter::WakeUp();
|
||||
}
|
||||
|
||||
@@ -850,33 +850,35 @@ static void CollectSample(Isolate* isolate,
|
||||
}
|
||||
|
||||
|
||||
// Is |isolate| executing Dart code?
|
||||
static bool ExecutingDart(Isolate* isolate) {
|
||||
ASSERT(isolate != NULL);
|
||||
return (isolate->top_exit_frame_info() == 0) &&
|
||||
(isolate->vm_tag() == VMTag::kDartTagId);
|
||||
// Is |thread| executing Dart code?
|
||||
static bool ExecutingDart(Thread* thread) {
|
||||
ASSERT(thread != NULL);
|
||||
return (thread->top_exit_frame_info() == 0) &&
|
||||
(thread->vm_tag() == VMTag::kDartTagId);
|
||||
}
|
||||
|
||||
|
||||
// Has |isolate| exited Dart code?
|
||||
static bool ExitedDart(Isolate* isolate) {
|
||||
return (isolate->top_exit_frame_info() != 0) &&
|
||||
(isolate->vm_tag() != VMTag::kDartTagId);
|
||||
// Has |thread| exited Dart code?
|
||||
static bool ExitedDart(Thread* thread) {
|
||||
return (thread->top_exit_frame_info() != 0) &&
|
||||
(thread->vm_tag() != VMTag::kDartTagId);
|
||||
}
|
||||
|
||||
|
||||
// Get |isolate|'s stack boundary and verify that |sp| and |fp| are within
|
||||
// it. Return |false| if anything looks suspicious.
|
||||
static bool GetAndValidateIsolateStackBounds(Isolate* isolate,
|
||||
static bool GetAndValidateIsolateStackBounds(Thread* thread,
|
||||
uintptr_t sp,
|
||||
uintptr_t fp,
|
||||
uword* stack_lower,
|
||||
uword* stack_upper) {
|
||||
ASSERT(thread != NULL);
|
||||
Isolate* isolate = thread->isolate();
|
||||
ASSERT(isolate != NULL);
|
||||
ASSERT(stack_lower != NULL);
|
||||
ASSERT(stack_upper != NULL);
|
||||
#if defined(USING_SIMULATOR)
|
||||
const bool in_dart_code = ExecutingDart(isolate);
|
||||
const bool in_dart_code = ExecutingDart(thread);
|
||||
if (in_dart_code) {
|
||||
Simulator* simulator = isolate->simulator();
|
||||
*stack_lower = simulator->StackBase();
|
||||
@@ -948,14 +950,15 @@ static SampleBuffer* GetSampleBuffer(Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
static Sample* SetupSample(Isolate* isolate,
|
||||
static Sample* SetupSample(Thread* thread,
|
||||
SampleBuffer* sample_buffer,
|
||||
ThreadId tid) {
|
||||
ASSERT(isolate != NULL);
|
||||
ASSERT(thread != NULL);
|
||||
Isolate* isolate = thread->isolate();
|
||||
ASSERT(sample_buffer != NULL);
|
||||
Sample* sample = sample_buffer->ReserveSample();
|
||||
sample->Init(isolate, OS::GetCurrentTimeMicros(), tid);
|
||||
uword vm_tag = isolate->vm_tag();
|
||||
uword vm_tag = thread->vm_tag();
|
||||
#if defined(USING_SIMULATOR)
|
||||
// When running in the simulator, the runtime entry function address
|
||||
// (stored as the vm tag) is the address of a redirect function.
|
||||
@@ -993,12 +996,14 @@ static uintptr_t __attribute__((noinline)) GetProgramCounter() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void Profiler::RecordAllocation(Isolate* isolate, intptr_t cid) {
|
||||
void Profiler::RecordAllocation(Thread* thread, intptr_t cid) {
|
||||
ASSERT(thread != NULL);
|
||||
Isolate* isolate = thread->isolate();
|
||||
if (!CheckIsolate(isolate)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool exited_dart_code = ExitedDart(isolate);
|
||||
const bool exited_dart_code = ExitedDart(thread);
|
||||
|
||||
SampleBuffer* sample_buffer = GetSampleBuffer(isolate);
|
||||
if (sample_buffer == NULL) {
|
||||
@@ -1020,7 +1025,7 @@ void Profiler::RecordAllocation(Isolate* isolate, intptr_t cid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetAndValidateIsolateStackBounds(isolate,
|
||||
if (!GetAndValidateIsolateStackBounds(thread,
|
||||
sp,
|
||||
fp,
|
||||
&stack_lower,
|
||||
@@ -1029,7 +1034,7 @@ void Profiler::RecordAllocation(Isolate* isolate, intptr_t cid) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sample* sample = SetupSample(isolate,
|
||||
Sample* sample = SetupSample(thread,
|
||||
sample_buffer,
|
||||
OSThread::GetCurrentThreadId());
|
||||
sample->SetAllocationCid(cid);
|
||||
@@ -1043,7 +1048,7 @@ void Profiler::RecordAllocation(Isolate* isolate, intptr_t cid) {
|
||||
sp);
|
||||
native_stack_walker.walk();
|
||||
} else if (exited_dart_code) {
|
||||
Sample* sample = SetupSample(isolate,
|
||||
Sample* sample = SetupSample(thread,
|
||||
sample_buffer,
|
||||
OSThread::GetCurrentThreadId());
|
||||
sample->SetAllocationCid(cid);
|
||||
@@ -1054,7 +1059,7 @@ void Profiler::RecordAllocation(Isolate* isolate, intptr_t cid) {
|
||||
} else {
|
||||
// Fall back.
|
||||
uintptr_t pc = GetProgramCounter();
|
||||
Sample* sample = SetupSample(isolate,
|
||||
Sample* sample = SetupSample(thread,
|
||||
sample_buffer,
|
||||
OSThread::GetCurrentThreadId());
|
||||
sample->SetAllocationCid(cid);
|
||||
@@ -1067,7 +1072,8 @@ void Profiler::RecordAllocation(Isolate* isolate, intptr_t cid) {
|
||||
void Profiler::RecordSampleInterruptCallback(
|
||||
const InterruptedThreadState& state,
|
||||
void* data) {
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(data);
|
||||
Thread* thread = reinterpret_cast<Thread*>(data);
|
||||
Isolate* isolate = thread->isolate();
|
||||
if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
|
||||
// No isolate.
|
||||
return;
|
||||
@@ -1080,8 +1086,8 @@ void Profiler::RecordSampleInterruptCallback(
|
||||
return;
|
||||
}
|
||||
|
||||
const bool exited_dart_code = ExitedDart(isolate);
|
||||
const bool in_dart_code = ExecutingDart(isolate);
|
||||
const bool exited_dart_code = ExitedDart(thread);
|
||||
const bool in_dart_code = ExecutingDart(thread);
|
||||
|
||||
uintptr_t sp = 0;
|
||||
uintptr_t fp = state.fp;
|
||||
@@ -1118,7 +1124,7 @@ void Profiler::RecordSampleInterruptCallback(
|
||||
|
||||
uword stack_lower = 0;
|
||||
uword stack_upper = 0;
|
||||
if (!GetAndValidateIsolateStackBounds(isolate,
|
||||
if (!GetAndValidateIsolateStackBounds(thread,
|
||||
sp,
|
||||
fp,
|
||||
&stack_lower,
|
||||
@@ -1131,7 +1137,7 @@ void Profiler::RecordSampleInterruptCallback(
|
||||
// know that our initial stack and frame pointers are within the boundary.
|
||||
|
||||
// Setup sample.
|
||||
Sample* sample = SetupSample(isolate,
|
||||
Sample* sample = SetupSample(thread,
|
||||
sample_buffer,
|
||||
OSThread::GetCurrentThreadId());
|
||||
// Increment counter for vm tag.
|
||||
|
||||
@@ -44,7 +44,7 @@ class Profiler : public AllStatic {
|
||||
return sample_buffer_;
|
||||
}
|
||||
|
||||
static void RecordAllocation(Isolate* isolate, intptr_t cid);
|
||||
static void RecordAllocation(Thread* thread, intptr_t cid);
|
||||
|
||||
private:
|
||||
static bool initialized_;
|
||||
|
||||
@@ -3868,7 +3868,7 @@ void Simulator::Longjmp(uword pc,
|
||||
set_register(FP, static_cast<int32_t>(fp));
|
||||
set_register(THR, reinterpret_cast<uword>(thread));
|
||||
// Set the tag.
|
||||
isolate->set_vm_tag(VMTag::kDartTagId);
|
||||
thread->set_vm_tag(VMTag::kDartTagId);
|
||||
// Clear top exit frame.
|
||||
isolate->set_top_exit_frame_info(0);
|
||||
|
||||
|
||||
@@ -3528,7 +3528,7 @@ void Simulator::Longjmp(uword pc,
|
||||
set_register(NULL, FP, static_cast<int64_t>(fp));
|
||||
set_register(NULL, THR, reinterpret_cast<int64_t>(thread));
|
||||
// Set the tag.
|
||||
isolate->set_vm_tag(VMTag::kDartTagId);
|
||||
thread->set_vm_tag(VMTag::kDartTagId);
|
||||
// Clear top exit frame.
|
||||
isolate->set_top_exit_frame_info(0);
|
||||
|
||||
|
||||
@@ -2476,7 +2476,7 @@ void Simulator::Longjmp(uword pc,
|
||||
set_register(FP, static_cast<int32_t>(fp));
|
||||
set_register(THR, reinterpret_cast<int32_t>(thread));
|
||||
// Set the tag.
|
||||
isolate->set_vm_tag(VMTag::kDartTagId);
|
||||
thread->set_vm_tag(VMTag::kDartTagId);
|
||||
// Clear top exit frame.
|
||||
isolate->set_top_exit_frame_info(0);
|
||||
|
||||
|
||||
+20
-32
@@ -45,9 +45,6 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R7)) != 0);
|
||||
__ LoadIsolate(R7);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to Dart VM C++ code.
|
||||
__ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -55,7 +52,7 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ LoadFromOffset(kWord, R6, R7, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
|
||||
__ CompareImmediate(R6, VMTag::kDartTagId);
|
||||
__ b(&ok, EQ);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
@@ -63,8 +60,8 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing VM code.
|
||||
__ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset());
|
||||
// Mark that the thread is executing VM code.
|
||||
__ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reserve space for arguments and align frame before entering C++ world.
|
||||
// NativeArguments are passed in registers.
|
||||
@@ -94,9 +91,9 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
// Call runtime or redirection via simulator.
|
||||
__ blx(R5);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(kWord, R2, R7, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ LoadImmediate(R2, 0);
|
||||
@@ -140,9 +137,6 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R7)) != 0);
|
||||
__ LoadIsolate(R7);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -150,7 +144,7 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ LoadFromOffset(kWord, R6, R7, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
|
||||
__ CompareImmediate(R6, VMTag::kDartTagId);
|
||||
__ b(&ok, EQ);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
@@ -158,8 +152,8 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset());
|
||||
// Mark that the thread is executing native code.
|
||||
__ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reserve space for the native arguments structure passed on the stack (the
|
||||
// outgoing pointer parameter to the native arguments structure is passed in
|
||||
@@ -197,9 +191,9 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
__ ldr(LR, Address(THR, Thread::native_call_wrapper_entry_point_offset()));
|
||||
__ blx(LR);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(kWord, R2, R7, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ LoadImmediate(R2, 0);
|
||||
@@ -224,9 +218,6 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R7)) != 0);
|
||||
__ LoadIsolate(R7);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -234,7 +225,7 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ LoadFromOffset(kWord, R6, R7, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
|
||||
__ CompareImmediate(R6, VMTag::kDartTagId);
|
||||
__ b(&ok, EQ);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
@@ -242,8 +233,8 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset());
|
||||
// Mark that the thread is executing native code.
|
||||
__ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reserve space for the native arguments structure passed on the stack (the
|
||||
// outgoing pointer parameter to the native arguments structure is passed in
|
||||
@@ -278,9 +269,9 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
// Call native function or redirection via simulator.
|
||||
__ blx(R5);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(kWord, R2, R7, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ LoadImmediate(R2, 0);
|
||||
@@ -761,15 +752,14 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
if (THR != R3) {
|
||||
__ mov(THR, Operand(R3));
|
||||
}
|
||||
__ LoadIsolate(R7);
|
||||
|
||||
// Save the current VMTag on the stack.
|
||||
__ LoadFromOffset(kWord, R5, R7, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(kWord, R5, THR, Thread::vm_tag_offset());
|
||||
__ Push(R5);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R5, VMTag::kDartTagId);
|
||||
__ StoreToOffset(kWord, R5, R7, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Save top resource and top exit frame info. Use R4-6 as temporary registers.
|
||||
// StackFrameIterator reads the top exit frame info saved in this frame.
|
||||
@@ -819,7 +809,6 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
// Get rid of arguments pushed on the stack.
|
||||
__ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
|
||||
|
||||
__ LoadIsolate(R7);
|
||||
// Restore the saved top exit frame info and top resource back into the
|
||||
// Isolate structure. Uses R5 as a temporary register for this.
|
||||
__ Pop(R5);
|
||||
@@ -829,7 +818,7 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
|
||||
// Restore the current VMTag from the stack.
|
||||
__ Pop(R4);
|
||||
__ StoreToOffset(kWord, R4, R7, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(kWord, R4, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Restore C++ ABI callee-saved registers.
|
||||
if (TargetCPUFeatures::vfp_supported()) {
|
||||
@@ -1901,10 +1890,9 @@ void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
|
||||
__ ldr(THR, Address(SP, 4)); // Thread.
|
||||
__ mov(FP, Operand(R2)); // Frame_pointer.
|
||||
__ mov(SP, Operand(IP)); // Set Stack pointer.
|
||||
__ LoadIsolate(R3);
|
||||
// Set the tag.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(kWord, R2, R3, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
|
||||
// Clear top exit frame.
|
||||
__ LoadImmediate(R2, 0);
|
||||
__ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset());
|
||||
|
||||
@@ -46,9 +46,6 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
__ Comment("CallToRuntimeStub");
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0);
|
||||
__ LoadIsolate(R28);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to Dart VM C++ code.
|
||||
__ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -56,7 +53,7 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ LoadFromOffset(R8, R28, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(R8, THR, Thread::vm_tag_offset());
|
||||
__ CompareImmediate(R8, VMTag::kDartTagId);
|
||||
__ b(&ok, EQ);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
@@ -64,8 +61,8 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing VM code.
|
||||
__ StoreToOffset(R5, R28, Isolate::vm_tag_offset());
|
||||
// Mark that the thread is executing VM code.
|
||||
__ StoreToOffset(R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reserve space for arguments and align frame before entering C++ world.
|
||||
// NativeArguments are passed in registers.
|
||||
@@ -115,9 +112,9 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
__ mov(CSP, R26);
|
||||
|
||||
// Retval is next to 1st argument.
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(R2, R28, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(R2, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -153,9 +150,6 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0);
|
||||
__ LoadIsolate(R28);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -163,7 +157,7 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ LoadFromOffset(R6, R28, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(R6, THR, Thread::vm_tag_offset());
|
||||
__ CompareImmediate(R6, VMTag::kDartTagId);
|
||||
__ b(&ok, EQ);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
@@ -171,8 +165,8 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ StoreToOffset(R5, R28, Isolate::vm_tag_offset());
|
||||
// Mark that the thread is executing native code.
|
||||
__ StoreToOffset(R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reserve space for the native arguments structure passed on the stack (the
|
||||
// outgoing pointer parameter to the native arguments structure is passed in
|
||||
@@ -223,9 +217,9 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
__ mov(SP, CSP);
|
||||
__ mov(CSP, R26);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(R2, R28, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(R2, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -249,9 +243,6 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0);
|
||||
__ LoadIsolate(R28);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -259,7 +250,7 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ LoadFromOffset(R6, R28, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(R6, THR, Thread::vm_tag_offset());
|
||||
__ CompareImmediate(R6, VMTag::kDartTagId);
|
||||
__ b(&ok, EQ);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
@@ -267,8 +258,8 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ StoreToOffset(R5, R28, Isolate::vm_tag_offset());
|
||||
// Mark that the thread is executing native code.
|
||||
__ StoreToOffset(R5, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reserve space for the native arguments structure passed on the stack (the
|
||||
// outgoing pointer parameter to the native arguments structure is passed in
|
||||
@@ -316,9 +307,9 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
__ mov(SP, CSP);
|
||||
__ mov(CSP, R26);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(R2, R28, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(R2, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
|
||||
@@ -821,16 +812,14 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
if (THR != R3) {
|
||||
__ mov(THR, R3);
|
||||
}
|
||||
// Load Isolate pointer into temporary register R5.
|
||||
__ LoadIsolate(R5);
|
||||
|
||||
// Save the current VMTag on the stack.
|
||||
__ LoadFromOffset(R4, R5, Isolate::vm_tag_offset());
|
||||
__ LoadFromOffset(R4, THR, Thread::vm_tag_offset());
|
||||
__ Push(R4);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(R6, VMTag::kDartTagId);
|
||||
__ StoreToOffset(R6, R5, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(R6, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Save top resource and top exit frame info. Use R6 as a temporary register.
|
||||
// StackFrameIterator reads the top exit frame info saved in this frame.
|
||||
@@ -883,8 +872,6 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
// Get rid of arguments pushed on the stack.
|
||||
__ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
|
||||
|
||||
__ LoadIsolate(R28);
|
||||
|
||||
// Restore the saved top exit frame info and top resource back into the
|
||||
// Isolate structure. Uses R6 as a temporary register for this.
|
||||
__ Pop(R6);
|
||||
@@ -894,7 +881,7 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
|
||||
// Restore the current VMTag from the stack.
|
||||
__ Pop(R4);
|
||||
__ StoreToOffset(R4, R28, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(R4, THR, Thread::vm_tag_offset());
|
||||
|
||||
// Restore the bottom 64-bits of callee-saved V registers.
|
||||
for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
|
||||
@@ -1973,10 +1960,9 @@ void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
|
||||
__ mov(R0, R3); // Exception object.
|
||||
__ mov(R1, R4); // StackTrace object.
|
||||
__ mov(THR, R5);
|
||||
__ LoadIsolate(R5);
|
||||
// Set the tag.
|
||||
__ LoadImmediate(R2, VMTag::kDartTagId);
|
||||
__ StoreToOffset(R2, R5, Isolate::vm_tag_offset());
|
||||
__ StoreToOffset(R2, THR, Thread::vm_tag_offset());
|
||||
// Clear top exit frame.
|
||||
__ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
|
||||
__ ret(); // Jump to the exception handler code.
|
||||
|
||||
@@ -49,8 +49,6 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
|
||||
__ EnterFrame(0);
|
||||
|
||||
__ LoadIsolate(EDI);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to Dart VM C++ code.
|
||||
__ movl(Address(THR, Thread::top_exit_frame_info_offset()), EBP);
|
||||
@@ -58,16 +56,15 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ cmpl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
__ j(EQUAL, &ok, Assembler::kNearJump);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing VM code.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()), ECX);
|
||||
// Mark that the thread is executing VM code.
|
||||
__ movl(Assembler::VMTagAddress(), ECX);
|
||||
|
||||
// Reserve space for arguments and align frame before entering C++ world.
|
||||
__ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments)));
|
||||
@@ -87,9 +84,7 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
__ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments.
|
||||
__ call(ECX);
|
||||
|
||||
// Mark that the isolate is executing Dart code. EDI is callee saved.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
@@ -125,7 +120,6 @@ void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
|
||||
// EAX : address of first argument in argument array.
|
||||
// ECX : address of the native function to call.
|
||||
// EDX : argc_tag including number of arguments and function kind.
|
||||
// Uses EDI.
|
||||
void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
const intptr_t native_args_struct_offset =
|
||||
NativeEntry::kNumCallWrapperArguments * kWordSize;
|
||||
@@ -140,7 +134,6 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterFrame(0);
|
||||
|
||||
__ LoadIsolate(EDI);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to dart VM code.
|
||||
@@ -149,16 +142,15 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ cmpl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
__ j(EQUAL, &ok, Assembler::kNearJump);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()), ECX);
|
||||
// Mark that the thread is executing native code.
|
||||
__ movl(Assembler::VMTagAddress(), ECX);
|
||||
|
||||
// Reserve space for the native arguments structure, the outgoing parameters
|
||||
// (pointer to the native arguments structure, the C function entry point)
|
||||
@@ -182,9 +174,7 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
ExternalLabel label(NativeEntry::NativeCallWrapperEntry());
|
||||
__ call(&label);
|
||||
|
||||
// Mark that the isolate is executing Dart code. EDI is callee saved.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
@@ -200,7 +190,6 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
// EAX : address of first argument in argument array.
|
||||
// ECX : address of the native function to call.
|
||||
// EDX : argc_tag including number of arguments and function kind.
|
||||
// Uses EDI.
|
||||
void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
const intptr_t native_args_struct_offset = kWordSize;
|
||||
const intptr_t thread_offset =
|
||||
@@ -214,8 +203,6 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterFrame(0);
|
||||
|
||||
__ LoadIsolate(EDI);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to dart VM code.
|
||||
__ movl(Address(THR, Thread::top_exit_frame_info_offset()), EBP);
|
||||
@@ -223,16 +210,15 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ cmpl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
__ j(EQUAL, &ok, Assembler::kNearJump);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()), ECX);
|
||||
// Mark that the thread is executing native code.
|
||||
__ movl(Assembler::VMTagAddress(), ECX);
|
||||
|
||||
// Reserve space for the native arguments structure, the outgoing parameter
|
||||
// (pointer to the native arguments structure) and align frame before
|
||||
@@ -252,9 +238,7 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
__ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments.
|
||||
__ call(ECX);
|
||||
|
||||
// Mark that the isolate is executing Dart code. EDI is callee saved.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
@@ -721,15 +705,13 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
|
||||
// Set up THR, which caches the current thread in Dart code.
|
||||
__ movl(THR, EAX);
|
||||
__ LoadIsolate(EDI);
|
||||
|
||||
// Save the current VMTag on the stack.
|
||||
__ movl(ECX, Address(EDI, Isolate::vm_tag_offset()));
|
||||
__ movl(ECX, Assembler::VMTagAddress());
|
||||
__ pushl(ECX);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Save top resource and top exit frame info. Use EDX as a temporary register.
|
||||
// StackFrameIterator reads the top exit frame info saved in this frame.
|
||||
@@ -786,12 +768,11 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
|
||||
// Restore the saved top exit frame info and top resource back into the
|
||||
// Isolate structure.
|
||||
__ LoadIsolate(EDI);
|
||||
__ popl(Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
__ popl(Address(THR, Thread::top_resource_offset()));
|
||||
|
||||
// Restore the current VMTag from the stack.
|
||||
__ popl(Address(EDI, Isolate::vm_tag_offset()));
|
||||
__ popl(Assembler::VMTagAddress());
|
||||
|
||||
// Restore C++ ABI callee-saved registers.
|
||||
__ popl(EDI);
|
||||
@@ -1897,11 +1878,8 @@ void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
|
||||
__ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer.
|
||||
__ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX.
|
||||
__ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer.
|
||||
// TODO(koda): Pass thread instead of isolate.
|
||||
__ LoadIsolate(EDI);
|
||||
// Set tag.
|
||||
__ movl(Address(EDI, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
// Clear top exit frame.
|
||||
__ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
__ jmp(EBX); // Jump to the exception handler code.
|
||||
|
||||
@@ -46,9 +46,6 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
__ Comment("CallToRuntimeStub");
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S2)) != 0);
|
||||
__ LoadIsolate(S2);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to Dart VM C++ code.
|
||||
__ sw(FP, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
@@ -56,15 +53,15 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ lw(T0, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ lw(T0, Assembler::VMTagAddress());
|
||||
__ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing VM code.
|
||||
__ sw(S5, Address(S2, Isolate::vm_tag_offset()));
|
||||
// Mark that the thread is executing VM code.
|
||||
__ sw(S5, Assembler::VMTagAddress());
|
||||
|
||||
// Reserve space for arguments and align frame before entering C++ world.
|
||||
// NativeArguments are passed in registers.
|
||||
@@ -101,9 +98,9 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
__ delay_slot()->addiu(A3, A2, Immediate(kWordSize));
|
||||
__ Comment("CallToRuntimeStub return");
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(A2, VMTag::kDartTagId);
|
||||
__ sw(A2, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ sw(A2, Assembler::VMTagAddress());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ sw(ZR, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
@@ -147,9 +144,6 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
__ Comment("CallNativeCFunctionStub");
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S2)) != 0);
|
||||
__ LoadIsolate(S2);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ sw(FP, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
@@ -157,15 +151,15 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ lw(T0, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ lw(T0, Assembler::VMTagAddress());
|
||||
__ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ sw(T5, Address(S2, Isolate::vm_tag_offset()));
|
||||
// Mark that the thread is executing native code.
|
||||
__ sw(T5, Assembler::VMTagAddress());
|
||||
|
||||
// Initialize NativeArguments structure and call native function.
|
||||
// Registers A0, A1, A2, and A3 are used.
|
||||
@@ -205,9 +199,9 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
__ jalr(T9);
|
||||
__ Comment("CallNativeCFunctionStub return");
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(A2, VMTag::kDartTagId);
|
||||
__ sw(A2, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ sw(A2, Assembler::VMTagAddress());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ sw(ZR, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
@@ -232,9 +226,6 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
__ Comment("CallNativeCFunctionStub");
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S2)) != 0);
|
||||
__ LoadIsolate(S2);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ sw(FP, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
@@ -242,15 +233,15 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
#if defined(DEBUG)
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ lw(T0, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ lw(T0, Assembler::VMTagAddress());
|
||||
__ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ sw(T5, Address(S2, Isolate::vm_tag_offset()));
|
||||
// Mark that the thread is executing native code.
|
||||
__ sw(T5, Assembler::VMTagAddress());
|
||||
|
||||
// Initialize NativeArguments structure and call native function.
|
||||
// Registers A0, A1, A2, and A3 are used.
|
||||
@@ -291,9 +282,9 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
__ jalr(T9);
|
||||
__ Comment("CallNativeCFunctionStub return");
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(A2, VMTag::kDartTagId);
|
||||
__ sw(A2, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ sw(A2, Assembler::VMTagAddress());
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ sw(ZR, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
@@ -835,15 +826,14 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
if (THR != A3) {
|
||||
__ mov(THR, A3);
|
||||
}
|
||||
__ LoadIsolate(T2);
|
||||
|
||||
// Save the current VMTag on the stack.
|
||||
__ lw(T1, Address(T2, Isolate::vm_tag_offset()));
|
||||
__ lw(T1, Assembler::VMTagAddress());
|
||||
__ sw(T1, Address(SP, 2 * kWordSize));
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ LoadImmediate(T0, VMTag::kDartTagId);
|
||||
__ sw(T0, Address(T2, Isolate::vm_tag_offset()));
|
||||
__ sw(T0, Assembler::VMTagAddress());
|
||||
|
||||
// Save top resource and top exit frame info. Use T0 as a temporary register.
|
||||
// StackFrameIterator reads the top exit frame info saved in this frame.
|
||||
@@ -896,11 +886,10 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
// Get rid of arguments pushed on the stack.
|
||||
__ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
|
||||
|
||||
__ LoadIsolate(S2);
|
||||
|
||||
// Restore the current VMTag from the stack.
|
||||
__ lw(T1, Address(SP, 2 * kWordSize));
|
||||
__ sw(T1, Address(S2, Isolate::vm_tag_offset()));
|
||||
__ sw(T1, Assembler::VMTagAddress());
|
||||
|
||||
// Restore the saved top resource and top exit frame info back into the
|
||||
// Isolate structure. Uses T0 as a temporary register for this.
|
||||
@@ -2048,10 +2037,9 @@ void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
|
||||
__ lw(V1, Address(SP, 4 * kWordSize)); // StackTrace object.
|
||||
__ mov(FP, A2); // Frame_pointer.
|
||||
__ lw(THR, Address(SP, 5 * kWordSize)); // Thread.
|
||||
__ LoadIsolate(A3);
|
||||
// Set tag.
|
||||
__ LoadImmediate(A2, VMTag::kDartTagId);
|
||||
__ sw(A2, Address(A3, Isolate::vm_tag_offset()));
|
||||
__ sw(A2, Assembler::VMTagAddress());
|
||||
// Clear top exit frame.
|
||||
__ sw(ZR, Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
|
||||
|
||||
+20
-44
@@ -46,10 +46,6 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT(
|
||||
(CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0);
|
||||
__ LoadIsolate(R12);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to Dart VM C++ code.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
|
||||
@@ -58,15 +54,15 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ movq(RAX, Immediate(VMTag::kDartTagId));
|
||||
__ cmpq(RAX, Address(R12, Isolate::vm_tag_offset()));
|
||||
__ cmpq(RAX, Assembler::VMTagAddress());
|
||||
__ j(EQUAL, &ok, Assembler::kNearJump);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing VM code.
|
||||
__ movq(Address(R12, Isolate::vm_tag_offset()), RBX);
|
||||
// Mark that the thread is executing VM code.
|
||||
__ movq(Assembler::VMTagAddress(), RBX);
|
||||
|
||||
// Reserve space for arguments and align frame before entering C++ world.
|
||||
__ subq(RSP, Immediate(sizeof(NativeArguments)));
|
||||
@@ -90,9 +86,8 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
|
||||
#endif
|
||||
__ CallCFunction(RBX);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
__ movq(Address(R12, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
@@ -144,10 +139,6 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT(
|
||||
(CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0);
|
||||
__ LoadIsolate(R12);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
|
||||
@@ -156,15 +147,15 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ movq(R8, Immediate(VMTag::kDartTagId));
|
||||
__ cmpq(R8, Address(R12, Isolate::vm_tag_offset()));
|
||||
__ cmpq(R8, Assembler::VMTagAddress());
|
||||
__ j(EQUAL, &ok, Assembler::kNearJump);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ movq(Address(R12, Isolate::vm_tag_offset()), RBX);
|
||||
// Mark that the thread is executing native code.
|
||||
__ movq(Assembler::VMTagAddress(), RBX);
|
||||
|
||||
// Reserve space for the native arguments structure passed on the stack (the
|
||||
// outgoing pointer parameter to the native arguments structure is passed in
|
||||
@@ -189,9 +180,8 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
|
||||
__ movq(RAX, Address(THR, Thread::native_call_wrapper_entry_point_offset()));
|
||||
__ CallCFunction(RAX);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
__ movq(Address(R12, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
@@ -220,10 +210,6 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
|
||||
__ EnterStubFrame();
|
||||
|
||||
COMPILE_ASSERT(
|
||||
(CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0);
|
||||
__ LoadIsolate(R12);
|
||||
|
||||
// Save exit frame information to enable stack walking as we are about
|
||||
// to transition to native code.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
|
||||
@@ -232,15 +218,15 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
{ Label ok;
|
||||
// Check that we are always entering from Dart code.
|
||||
__ movq(R8, Immediate(VMTag::kDartTagId));
|
||||
__ cmpq(R8, Address(R12, Isolate::vm_tag_offset()));
|
||||
__ cmpq(R8, Assembler::VMTagAddress());
|
||||
__ j(EQUAL, &ok, Assembler::kNearJump);
|
||||
__ Stop("Not coming from Dart code.");
|
||||
__ Bind(&ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark that the isolate is executing Native code.
|
||||
__ movq(Address(R12, Isolate::vm_tag_offset()), RBX);
|
||||
// Mark that the thread is executing native code.
|
||||
__ movq(Assembler::VMTagAddress(), RBX);
|
||||
|
||||
// Reserve space for the native arguments structure passed on the stack (the
|
||||
// outgoing pointer parameter to the native arguments structure is passed in
|
||||
@@ -261,9 +247,8 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
|
||||
__ movq(CallingConventions::kArg1Reg, RSP);
|
||||
__ CallCFunction(RBX);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
__ movq(Address(R12, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Reset exit frame information in Isolate structure.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
|
||||
@@ -753,17 +738,13 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
if (THR != kThreadReg) {
|
||||
__ movq(THR, kThreadReg);
|
||||
}
|
||||
// Load Isolate pointer into kIsolateReg.
|
||||
const Register kIsolateReg = RBX;
|
||||
__ LoadIsolate(kIsolateReg);
|
||||
|
||||
// Save the current VMTag on the stack.
|
||||
__ movq(RAX, Address(kIsolateReg, Isolate::vm_tag_offset()));
|
||||
__ movq(RAX, Assembler::VMTagAddress());
|
||||
__ pushq(RAX);
|
||||
|
||||
// Mark that the isolate is executing Dart code.
|
||||
__ movq(Address(kIsolateReg, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
// Mark that the thread is executing Dart code.
|
||||
__ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
|
||||
// Save top resource and top exit frame info. Use RAX as a temporary register.
|
||||
// StackFrameIterator reads the top exit frame info saved in this frame.
|
||||
@@ -833,12 +814,11 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
||||
|
||||
// Restore the saved top exit frame info and top resource back into the
|
||||
// Isolate structure.
|
||||
__ LoadIsolate(kIsolateReg);
|
||||
__ popq(Address(THR, Thread::top_exit_frame_info_offset()));
|
||||
__ popq(Address(THR, Thread::top_resource_offset()));
|
||||
|
||||
// Restore the current VMTag from the stack.
|
||||
__ popq(Address(kIsolateReg, Isolate::vm_tag_offset()));
|
||||
__ popq(Assembler::VMTagAddress());
|
||||
|
||||
// Restore C++ ABI callee-saved registers.
|
||||
__ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
|
||||
@@ -1961,20 +1941,16 @@ void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
|
||||
Register stacktrace_reg = RBX;
|
||||
__ movq(stacktrace_reg, Address(RSP, 5 * kWordSize));
|
||||
__ movq(THR, Address(RSP, 6 * kWordSize));
|
||||
Register isolate_reg = RDI;
|
||||
#else
|
||||
Register stacktrace_reg = CallingConventions::kArg5Reg;
|
||||
__ movq(THR, CallingConventions::kArg6Reg);
|
||||
Register isolate_reg = CallingConventions::kArg6Reg;
|
||||
#endif
|
||||
__ LoadIsolate(isolate_reg);
|
||||
__ movq(RBP, CallingConventions::kArg3Reg);
|
||||
__ movq(RSP, CallingConventions::kArg2Reg);
|
||||
__ movq(kStackTraceObjectReg, stacktrace_reg);
|
||||
__ movq(kExceptionObjectReg, CallingConventions::kArg4Reg);
|
||||
// Set the tag.
|
||||
__ movq(Address(isolate_reg, Isolate::vm_tag_offset()),
|
||||
Immediate(VMTag::kDartTagId));
|
||||
__ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId));
|
||||
// Clear top exit frame.
|
||||
__ movq(Address(THR, Thread::top_exit_frame_info_offset()),
|
||||
Immediate(0));
|
||||
|
||||
+3
-3
@@ -84,16 +84,16 @@ VMTag::TagEntry VMTag::entries_[] = {
|
||||
VMTagScope::VMTagScope(Thread* thread, uword tag, bool conditional_set)
|
||||
: StackResource(thread) {
|
||||
ASSERT(isolate() != NULL);
|
||||
previous_tag_ = isolate()->vm_tag();
|
||||
previous_tag_ = thread->vm_tag();
|
||||
if (conditional_set) {
|
||||
isolate()->set_vm_tag(tag);
|
||||
thread->set_vm_tag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VMTagScope::~VMTagScope() {
|
||||
ASSERT(isolate() != NULL);
|
||||
isolate()->set_vm_tag(previous_tag_);
|
||||
thread()->set_vm_tag(previous_tag_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -113,7 +113,8 @@ Thread::Thread(bool init_vm_constants)
|
||||
isolate_(NULL),
|
||||
heap_(NULL),
|
||||
store_buffer_block_(NULL),
|
||||
log_(new class Log()) {
|
||||
log_(new class Log()),
|
||||
vm_tag_(0) {
|
||||
ClearState();
|
||||
|
||||
#define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
|
||||
@@ -188,7 +189,7 @@ void Thread::EnterIsolate(Isolate* isolate) {
|
||||
ASSERT(!isolate->HasMutatorThread());
|
||||
thread->isolate_ = isolate;
|
||||
isolate->MakeCurrentThreadMutator(thread);
|
||||
isolate->set_vm_tag(VMTag::kVMTagId);
|
||||
thread->set_vm_tag(VMTag::kVMTagId);
|
||||
ASSERT(thread->store_buffer_block_ == NULL);
|
||||
thread->StoreBufferAcquire();
|
||||
ASSERT(isolate->heap() != NULL);
|
||||
@@ -209,9 +210,9 @@ void Thread::ExitIsolate() {
|
||||
// TODO(koda): Move store_buffer_block_ into State.
|
||||
thread->StoreBufferRelease();
|
||||
if (isolate->is_runnable()) {
|
||||
isolate->set_vm_tag(VMTag::kIdleTagId);
|
||||
thread->set_vm_tag(VMTag::kIdleTagId);
|
||||
} else {
|
||||
isolate->set_vm_tag(VMTag::kLoadWaitTagId);
|
||||
thread->set_vm_tag(VMTag::kLoadWaitTagId);
|
||||
}
|
||||
isolate->ClearMutatorThread();
|
||||
thread->isolate_ = NULL;
|
||||
|
||||
@@ -282,6 +282,16 @@ LEAF_RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD)
|
||||
state_.long_jump_base = value;
|
||||
}
|
||||
|
||||
uword vm_tag() const {
|
||||
return vm_tag_;
|
||||
}
|
||||
void set_vm_tag(uword tag) {
|
||||
vm_tag_ = tag;
|
||||
}
|
||||
static intptr_t vm_tag_offset() {
|
||||
return OFFSET_OF(Thread, vm_tag_);
|
||||
}
|
||||
|
||||
ThreadId id() const {
|
||||
ASSERT(id_ != OSThread::kInvalidThreadId);
|
||||
return id_;
|
||||
@@ -304,6 +314,7 @@ LEAF_RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD)
|
||||
Mutex timeline_block_lock_;
|
||||
StoreBufferBlock* store_buffer_block_;
|
||||
class Log* log_;
|
||||
uword vm_tag_;
|
||||
#define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \
|
||||
type_name member_name;
|
||||
CACHED_CONSTANTS_LIST(DECLARE_MEMBERS)
|
||||
|
||||
Reference in New Issue
Block a user