fea5413d5a
This is due to how Windows destroys objects as destroyed objects have their vtables reset to the vtable of the base class. If this happens when an isolate hasn't finished shutting down and a virtual function which is overriding a pure virtual function from the base class is called, _purecall() is invoked and attempts to call exit() again which leads to a deadlock. See issue #35855 for more details. Change-Id: I93a0e00549e7ee87a717a6cde01bf0848050384d Reviewed-on: https://dart-review.googlesource.com/c/92000 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
70 lines
2.6 KiB
C++
70 lines
2.6 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "vm/globals.h"
|
|
#if defined(TARGET_ARCH_ARM)
|
|
|
|
#include "vm/runtime_entry.h"
|
|
|
|
#include "vm/compiler/assembler/assembler.h"
|
|
#include "vm/simulator.h"
|
|
#include "vm/stub_code.h"
|
|
|
|
namespace dart {
|
|
|
|
#define __ assembler->
|
|
|
|
uword RuntimeEntry::GetEntryPoint() const {
|
|
// Compute the effective address. When running under the simulator,
|
|
// this is a redirection address that forces the simulator to call
|
|
// into the runtime system.
|
|
uword entry = reinterpret_cast<uword>(function());
|
|
#if defined(USING_SIMULATOR)
|
|
// Redirection to leaf runtime calls supports a maximum of 4 arguments passed
|
|
// in registers (maximum 2 double arguments for leaf float runtime calls).
|
|
ASSERT(argument_count() >= 0);
|
|
ASSERT(!is_leaf() || (!is_float() && (argument_count() <= 4)) ||
|
|
(argument_count() <= 2));
|
|
Simulator::CallKind call_kind =
|
|
is_leaf() ? (is_float() ? Simulator::kLeafFloatRuntimeCall
|
|
: Simulator::kLeafRuntimeCall)
|
|
: Simulator::kRuntimeCall;
|
|
entry =
|
|
Simulator::RedirectExternalReference(entry, call_kind, argument_count());
|
|
#endif
|
|
return entry;
|
|
}
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
// Generate code to call into the stub which will call the runtime
|
|
// function. Input for the stub is as follows:
|
|
// SP : points to the arguments and return value array.
|
|
// R9 : address of the runtime function to call.
|
|
// R4 : number of arguments to the call.
|
|
void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
|
|
Assembler* assembler,
|
|
intptr_t argument_count) {
|
|
if (runtime_entry->is_leaf()) {
|
|
ASSERT(argument_count == runtime_entry->argument_count());
|
|
__ LoadFromOffset(kWord, TMP, THR, Thread::OffsetFromThread(runtime_entry));
|
|
__ str(TMP, Address(THR, Thread::vm_tag_offset()));
|
|
__ blx(TMP);
|
|
__ LoadImmediate(TMP, VMTag::kDartCompiledTagId);
|
|
__ str(TMP, Address(THR, Thread::vm_tag_offset()));
|
|
ASSERT((kAbiPreservedCpuRegs & (1 << THR)) != 0);
|
|
ASSERT((kAbiPreservedCpuRegs & (1 << PP)) != 0);
|
|
} else {
|
|
// Argument count is not checked here, but in the runtime entry for a more
|
|
// informative error message.
|
|
__ LoadFromOffset(kWord, R9, THR, Thread::OffsetFromThread(runtime_entry));
|
|
__ LoadImmediate(R4, argument_count);
|
|
__ BranchLinkToRuntime();
|
|
}
|
|
}
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
} // namespace dart
|
|
|
|
#endif // defined TARGET_ARCH_ARM
|