mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge pull request #171 from joshuawarner32/master
Flatten "vm" dir and split signal handling out of vm::System
This commit is contained in:
commit
3912f2c0e4
@ -11,11 +11,11 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_H
|
#define AVIAN_CODEGEN_ASSEMBLER_H
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/zone.h"
|
#include "avian/zone.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef AVIAN_CODEGEN_COMPILER_H
|
#ifndef AVIAN_CODEGEN_COMPILER_H
|
||||||
#define AVIAN_CODEGEN_COMPILER_H
|
#define AVIAN_CODEGEN_COMPILER_H
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/zone.h"
|
#include "avian/zone.h"
|
||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
|
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef HEAP_H
|
#ifndef HEAP_H
|
||||||
#define HEAP_H
|
#define HEAP_H
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/allocator.h"
|
#include "avian/allocator.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
82
include/avian/system/signal.h
Normal file
82
include/avian/system/signal.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/* Copyright (c) 2008-2013, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_SYSTEM_SIGNAL_H
|
||||||
|
#define AVIAN_SYSTEM_SIGNAL_H
|
||||||
|
|
||||||
|
#include <avian/common.h>
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
// Crash the process.
|
||||||
|
// On posix, the just calls abort. On windows, we dereference a null pointer in
|
||||||
|
// order to trigger the crash dump logic.
|
||||||
|
NO_RETURN void crash();
|
||||||
|
|
||||||
|
// Registrar for unix-like "signals" (implemented with structured exceptions on windows).
|
||||||
|
// TODO: remove dependence on generated code having a well-known "thread"
|
||||||
|
// register. Use a thread-local variable instead.
|
||||||
|
class SignalRegistrar {
|
||||||
|
public:
|
||||||
|
class Handler {
|
||||||
|
public:
|
||||||
|
// This function receives state information about the paused thread.
|
||||||
|
// Returns whether to resume execution after the failure point.
|
||||||
|
virtual bool handleSignal(void** ip,
|
||||||
|
void** frame,
|
||||||
|
void** stack,
|
||||||
|
void** thread) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Signal {
|
||||||
|
// "Segmentation fault" exceptions (mostly null pointer dereference, but
|
||||||
|
// generally access to any non-mapped memory)
|
||||||
|
SegFault,
|
||||||
|
|
||||||
|
DivideByZero,
|
||||||
|
};
|
||||||
|
|
||||||
|
SignalRegistrar();
|
||||||
|
~SignalRegistrar();
|
||||||
|
|
||||||
|
// Register a handler for the given signal.
|
||||||
|
// After this method call, anytime the given signal is raised, it will be
|
||||||
|
// handled by the given handler.
|
||||||
|
// Returns true upon success, false upon failure
|
||||||
|
bool registerHandler(Signal signal, Handler* handler);
|
||||||
|
|
||||||
|
// Unregister a handler for the given signal.
|
||||||
|
// After this method call, the given signal will no longer be handled (or,
|
||||||
|
// rather, it go back to being handled by whatever was registered to handle it
|
||||||
|
// before us).
|
||||||
|
// Returns true upon success, false upon failure
|
||||||
|
bool unregisterHandler(Signal signal);
|
||||||
|
|
||||||
|
// Set the directory that a crash dump will be written to should an unhandled
|
||||||
|
// exception be thrown.
|
||||||
|
// Note: this only currently does anything on windows.
|
||||||
|
// TODO: move this out of this class, into a separate "CrashDumper" class or
|
||||||
|
// somesuch.
|
||||||
|
void setCrashDumpDirectory(const char* crashDumpDirectory);
|
||||||
|
|
||||||
|
// This is internal, implementation-specific data. It's declared in the
|
||||||
|
// specific implementation.
|
||||||
|
struct Data;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Data* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace system
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif
|
@ -98,12 +98,6 @@ class System : public avian::util::Aborter {
|
|||||||
virtual void disposeAll() = 0;
|
virtual void disposeAll() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SignalHandler {
|
|
||||||
public:
|
|
||||||
virtual bool handleSignal(void** ip, void** frame, void** stack,
|
|
||||||
void** thread) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MonitorResource {
|
class MonitorResource {
|
||||||
public:
|
public:
|
||||||
MonitorResource(System::Thread* t, System::Monitor* m): t(t), m(m) {
|
MonitorResource(System::Thread* t, System::Monitor* m): t(t), m(m) {
|
||||||
@ -131,8 +125,7 @@ class System : public avian::util::Aborter {
|
|||||||
virtual Status make(Mutex**) = 0;
|
virtual Status make(Mutex**) = 0;
|
||||||
virtual Status make(Monitor**) = 0;
|
virtual Status make(Monitor**) = 0;
|
||||||
virtual Status make(Local**) = 0;
|
virtual Status make(Local**) = 0;
|
||||||
virtual Status handleSegFault(SignalHandler* handler) = 0;
|
|
||||||
virtual Status handleDivideByZero(SignalHandler* handler) = 0;
|
|
||||||
virtual Status visit(Thread* thread, Thread* target,
|
virtual Status visit(Thread* thread, Thread* target,
|
||||||
ThreadVisitor* visitor) = 0;
|
ThreadVisitor* visitor) = 0;
|
||||||
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
||||||
@ -193,7 +186,7 @@ sysAbort(System* s)
|
|||||||
// #endif // not NDEBUG
|
// #endif // not NDEBUG
|
||||||
|
|
||||||
AVIAN_EXPORT System*
|
AVIAN_EXPORT System*
|
||||||
makeSystem(const char* crashDumpDirectory);
|
makeSystem();
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
14
makefile
14
makefile
@ -90,6 +90,12 @@ ifneq (,$(filter mingw32 cygwin,$(build-platform)))
|
|||||||
path-separator = ;
|
path-separator = ;
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
target-path-separator = :
|
||||||
|
|
||||||
|
ifeq ($(platform),windows)
|
||||||
|
target-path-separator = ;
|
||||||
|
endif
|
||||||
|
|
||||||
library-path-variable = LD_LIBRARY_PATH
|
library-path-variable = LD_LIBRARY_PATH
|
||||||
|
|
||||||
ifeq ($(build-platform),darwin)
|
ifeq ($(build-platform),darwin)
|
||||||
@ -1108,7 +1114,8 @@ vm-depends := $(generated-code) \
|
|||||||
$(shell find src include -name '*.h' -or -name '*.inc.cpp')
|
$(shell find src include -name '*.h' -or -name '*.inc.cpp')
|
||||||
|
|
||||||
vm-sources = \
|
vm-sources = \
|
||||||
$(src)/vm/system/$(system).cpp \
|
$(src)/system/$(system).cpp \
|
||||||
|
$(src)/system/$(system)/signal.cpp \
|
||||||
$(src)/finder.cpp \
|
$(src)/finder.cpp \
|
||||||
$(src)/machine.cpp \
|
$(src)/machine.cpp \
|
||||||
$(src)/util.cpp \
|
$(src)/util.cpp \
|
||||||
@ -1239,7 +1246,8 @@ boot-object = $(build)/boot.o
|
|||||||
generator-depends := $(wildcard $(src)/*.h)
|
generator-depends := $(wildcard $(src)/*.h)
|
||||||
generator-sources = \
|
generator-sources = \
|
||||||
$(src)/tools/type-generator/main.cpp \
|
$(src)/tools/type-generator/main.cpp \
|
||||||
$(src)/vm/system/$(build-system).cpp \
|
$(src)/system/$(build-system).cpp \
|
||||||
|
$(src)/system/$(build-system)/signal.cpp \
|
||||||
$(src)/finder.cpp
|
$(src)/finder.cpp
|
||||||
|
|
||||||
ifneq ($(lzma),)
|
ifneq ($(lzma),)
|
||||||
@ -1525,7 +1533,7 @@ endif
|
|||||||
$(build)/run-tests.sh: $(test-classes) makefile $(build)/extra-dir/multi-classpath-test.txt $(build)/test/multi-classpath-test.txt
|
$(build)/run-tests.sh: $(test-classes) makefile $(build)/extra-dir/multi-classpath-test.txt $(build)/test/multi-classpath-test.txt
|
||||||
echo 'cd $$(dirname $$0)' > $(@)
|
echo 'cd $$(dirname $$0)' > $(@)
|
||||||
echo "sh ./test.sh 2>/dev/null \\" >> $(@)
|
echo "sh ./test.sh 2>/dev/null \\" >> $(@)
|
||||||
echo "$(shell echo $(library-path) | sed 's|$(build)|\.|g') ./$(name)-unittest${exe-suffix} ./$(notdir $(test-executable)) $(mode) \"-Djava.library.path=. -cp test$(path-separator)extra-dir\" \\" >> $(@)
|
echo "$(shell echo $(library-path) | sed 's|$(build)|\.|g') ./$(name)-unittest${exe-suffix} ./$(notdir $(test-executable)) $(mode) \"-Djava.library.path=. -cp test$(target-path-separator)extra-dir\" \\" >> $(@)
|
||||||
echo "$(call class-names,$(test-build),$(filter-out $(test-support-classes), $(test-classes))) \\" >> $(@)
|
echo "$(call class-names,$(test-build),$(filter-out $(test-support-classes), $(test-classes))) \\" >> $(@)
|
||||||
echo "$(continuation-tests) $(tail-tests)" >> $(@)
|
echo "$(continuation-tests) $(tail-tests)" >> $(@)
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef VECTOR_H
|
#ifndef VECTOR_H
|
||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/target.h"
|
#include "avian/target.h"
|
||||||
|
|
||||||
#include <avian/util/math.h>
|
#include <avian/util/math.h>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#define FINDER_H
|
#define FINDER_H
|
||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/allocator.h"
|
#include "avian/allocator.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "avian/lzma.h"
|
#include "avian/lzma.h"
|
||||||
#include "C/Types.h"
|
#include "C/Types.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/allocator.h"
|
#include "avian/allocator.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef LZMA_H
|
#ifndef LZMA_H
|
||||||
#define LZMA_H
|
#define LZMA_H
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/allocator.h"
|
#include "avian/allocator.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include "java-common.h"
|
#include "java-common.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include <avian/vm/heap/heap.h>
|
#include <avian/system/signal.h>
|
||||||
|
#include <avian/heap/heap.h>
|
||||||
#include "avian/finder.h"
|
#include "avian/finder.h"
|
||||||
#include "avian/processor.h"
|
#include "avian/processor.h"
|
||||||
#include "avian/constants.h"
|
#include "avian/constants.h"
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#define PROCESS_H
|
#define PROCESS_H
|
||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/machine.h"
|
#include "avian/machine.h"
|
||||||
#include "avian/constants.h"
|
#include "avian/constants.h"
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#define PROCESSOR_H
|
#define PROCESSOR_H
|
||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include <avian/vm/heap/heap.h>
|
#include <avian/heap/heap.h>
|
||||||
#include "bootimage.h"
|
#include "bootimage.h"
|
||||||
#include "avian/heapwalk.h"
|
#include "avian/heapwalk.h"
|
||||||
#include "avian/zone.h"
|
#include "avian/zone.h"
|
||||||
@ -208,8 +208,10 @@ class Processor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Processor*
|
Processor* makeProcessor(System* system,
|
||||||
makeProcessor(System* system, Allocator* allocator, bool useNativeFeatures);
|
Allocator* allocator,
|
||||||
|
const char* crashDumpDirectory,
|
||||||
|
bool useNativeFeatures);
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef ZONE_H
|
#ifndef ZONE_H
|
||||||
#define ZONE_H
|
#define ZONE_H
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/allocator.h"
|
#include "avian/allocator.h"
|
||||||
|
|
||||||
#include <avian/util/math.h>
|
#include <avian/util/math.h>
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/compiler.h>
|
#include <avian/codegen/compiler.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
|
|
||||||
#include "codegen/compiler/regalloc.h"
|
#include "codegen/compiler/regalloc.h"
|
||||||
#include "codegen/compiler/context.h"
|
#include "codegen/compiler/context.h"
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "codegen/compiler/context.h"
|
#include "codegen/compiler/context.h"
|
||||||
#include "codegen/compiler/resource.h"
|
#include "codegen/compiler/resource.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
#ifndef AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
||||||
#define AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
#define AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/compiler.h>
|
#include <avian/codegen/compiler.h>
|
||||||
#include <avian/util/list.h>
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
#include "regalloc.h"
|
#include "regalloc.h"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "codegen/compiler/context.h"
|
#include "codegen/compiler/context.h"
|
||||||
#include "codegen/compiler/frame.h"
|
#include "codegen/compiler/frame.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
|
|
||||||
@ -108,4 +108,4 @@ pickTarget(Context* c, Read* read, bool intersectRead,
|
|||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_COMPILER_REGALLOC_H
|
#endif // AVIAN_CODEGEN_COMPILER_REGALLOC_H
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef AVIAN_CODEGEN_COMPILER_SITE_H
|
#ifndef AVIAN_CODEGEN_COMPILER_SITE_H
|
||||||
#define AVIAN_CODEGEN_COMPILER_SITE_H
|
#define AVIAN_CODEGEN_COMPILER_SITE_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
|
|
||||||
#include "codegen/compiler/value.h"
|
#include "codegen/compiler/value.h"
|
||||||
#include "codegen/compiler/context.h"
|
#include "codegen/compiler/context.h"
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_COMPILER_VALUE_H
|
#ifndef AVIAN_CODEGEN_COMPILER_VALUE_H
|
||||||
#define AVIAN_CODEGEN_COMPILER_VALUE_H
|
#define AVIAN_CODEGEN_COMPILER_VALUE_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/compiler.h>
|
#include <avian/codegen/compiler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
@ -81,4 +81,4 @@ Value* value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0);
|
|||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_COMPILER_VALUE_H
|
#endif // AVIAN_CODEGEN_COMPILER_VALUE_H
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_BLOCK_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_BLOCK_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_ARM_BLOCK_H
|
#define AVIAN_CODEGEN_ASSEMBLER_ARM_BLOCK_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_CONTEXT_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_CONTEXT_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_ARM_CONTEXT_H
|
#define AVIAN_CODEGEN_ASSEMBLER_ARM_CONTEXT_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include "avian/alloc-vector.h"
|
#include "avian/alloc-vector.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_ENCODE_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_ENCODE_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_ARM_ENCODE_H
|
#define AVIAN_CODEGEN_ASSEMBLER_ARM_ENCODE_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
#include "avian/target.h"
|
#include "avian/target.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include "avian/alloc-vector.h"
|
#include "avian/alloc-vector.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_MULTIMETHOD_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_MULTIMETHOD_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_ARM_MULTIMETHOD_H
|
#define AVIAN_CODEGEN_ASSEMBLER_ARM_MULTIMETHOD_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
||||||
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_REGISTERS_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_REGISTERS_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_ARM_REGISTERS_H
|
#define AVIAN_CODEGEN_ASSEMBLER_ARM_REGISTERS_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
|
|
||||||
#include "avian/alloc-vector.h"
|
#include "avian/alloc-vector.h"
|
||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include "avian/alloc-vector.h"
|
#include "avian/alloc-vector.h"
|
||||||
|
|
||||||
#ifdef powerpc
|
#ifdef powerpc
|
||||||
|
@ -22,13 +22,13 @@
|
|||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
#include <avian/util/math.h>
|
#include <avian/util/math.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_X86_BLOCK_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_X86_BLOCK_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_X86_BLOCK_H
|
#define AVIAN_CODEGEN_ASSEMBLER_X86_BLOCK_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
#include "avian/alloc-vector.h"
|
#include "avian/alloc-vector.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
class System;
|
class System;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_X86_DETECT_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_X86_DETECT_H
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_X86_DETECT_H
|
#define AVIAN_CODEGEN_ASSEMBLER_X86_DETECT_H
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
#include <avian/util/math.h>
|
#include <avian/util/math.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "encode.h"
|
#include "encode.h"
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
|
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "avian/zone.h"
|
#include "avian/zone.h"
|
||||||
|
|
||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "fixup.h"
|
#include "fixup.h"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
class System;
|
class System;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "operations.h"
|
#include "operations.h"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "encode.h"
|
#include "encode.h"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/targets.h>
|
#include <avian/codegen/targets.h>
|
||||||
|
|
||||||
#include "avian/environment.h"
|
#include "avian/environment.h"
|
||||||
|
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
#include "avian/target.h"
|
#include "avian/target.h"
|
||||||
#include "avian/arch.h"
|
#include "avian/arch.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
#include <avian/vm/codegen/compiler.h>
|
#include <avian/codegen/compiler.h>
|
||||||
#include <avian/vm/codegen/targets.h>
|
#include <avian/codegen/targets.h>
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/runtime.h>
|
#include <avian/codegen/runtime.h>
|
||||||
|
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
#include <avian/util/list.h>
|
#include <avian/util/list.h>
|
||||||
@ -43,6 +43,7 @@ vmJumpAndInvoke(void* thread, void* function, void* stack,
|
|||||||
unsigned frameSize);
|
unsigned frameSize);
|
||||||
|
|
||||||
using namespace avian::codegen;
|
using namespace avian::codegen;
|
||||||
|
using namespace avian::system;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -8366,7 +8367,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SignalHandler: public System::SignalHandler {
|
class SignalHandler: public SignalRegistrar::Handler {
|
||||||
public:
|
public:
|
||||||
SignalHandler(Machine::Type type, Machine::Root root, unsigned fixedSize):
|
SignalHandler(Machine::Type type, Machine::Root root, unsigned fixedSize):
|
||||||
m(0), type(type), root(root), fixedSize(fixedSize) { }
|
m(0), type(type), root(root), fixedSize(fixedSize) { }
|
||||||
@ -8501,24 +8502,27 @@ class MyProcessor: public Processor {
|
|||||||
Thunk table;
|
Thunk table;
|
||||||
};
|
};
|
||||||
|
|
||||||
MyProcessor(System* s, Allocator* allocator, bool useNativeFeatures):
|
MyProcessor(System* s,
|
||||||
s(s),
|
Allocator* allocator,
|
||||||
allocator(allocator),
|
const char* crashDumpDirectory,
|
||||||
roots(0),
|
bool useNativeFeatures)
|
||||||
bootImage(0),
|
: s(s),
|
||||||
heapImage(0),
|
allocator(allocator),
|
||||||
codeImage(0),
|
roots(0),
|
||||||
codeImageSize(0),
|
bootImage(0),
|
||||||
segFaultHandler(Machine::NullPointerExceptionType,
|
heapImage(0),
|
||||||
Machine::NullPointerException,
|
codeImage(0),
|
||||||
FixedSizeOfNullPointerException),
|
codeImageSize(0),
|
||||||
divideByZeroHandler(Machine::ArithmeticExceptionType,
|
segFaultHandler(Machine::NullPointerExceptionType,
|
||||||
Machine::ArithmeticException,
|
Machine::NullPointerException,
|
||||||
FixedSizeOfArithmeticException),
|
FixedSizeOfNullPointerException),
|
||||||
codeAllocator(s, 0, 0),
|
divideByZeroHandler(Machine::ArithmeticExceptionType,
|
||||||
callTableSize(0),
|
Machine::ArithmeticException,
|
||||||
useNativeFeatures(useNativeFeatures),
|
FixedSizeOfArithmeticException),
|
||||||
compilationHandlers(0)
|
codeAllocator(s, 0, 0),
|
||||||
|
callTableSize(0),
|
||||||
|
useNativeFeatures(useNativeFeatures),
|
||||||
|
compilationHandlers(0)
|
||||||
{
|
{
|
||||||
thunkTable[compileMethodIndex] = voidPointer(local::compileMethod);
|
thunkTable[compileMethodIndex] = voidPointer(local::compileMethod);
|
||||||
thunkTable[compileVirtualMethodIndex] = voidPointer(compileVirtualMethod);
|
thunkTable[compileVirtualMethodIndex] = voidPointer(compileVirtualMethod);
|
||||||
@ -8540,6 +8544,8 @@ class MyProcessor: public Processor {
|
|||||||
// table.
|
// table.
|
||||||
thunkTable[dummyIndex] = reinterpret_cast<void*>
|
thunkTable[dummyIndex] = reinterpret_cast<void*>
|
||||||
(static_cast<uintptr_t>(UINT64_C(0x5555555555555555)));
|
(static_cast<uintptr_t>(UINT64_C(0x5555555555555555)));
|
||||||
|
|
||||||
|
signals.setCrashDumpDirectory(crashDumpDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Thread*
|
virtual Thread*
|
||||||
@ -8924,7 +8930,9 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
compilationHandlers->dispose(allocator);
|
compilationHandlers->dispose(allocator);
|
||||||
|
|
||||||
s->handleSegFault(0);
|
signals.unregisterHandler(SignalRegistrar::SegFault);
|
||||||
|
signals.unregisterHandler(SignalRegistrar::DivideByZero);
|
||||||
|
signals.setCrashDumpDirectory(0);
|
||||||
|
|
||||||
allocator->free(this, sizeof(*this));
|
allocator->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
@ -9116,12 +9124,10 @@ class MyProcessor: public Processor {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
segFaultHandler.m = t->m;
|
segFaultHandler.m = t->m;
|
||||||
expect(t, t->m->system->success
|
expect(t, signals.registerHandler(SignalRegistrar::SegFault, &segFaultHandler));
|
||||||
(t->m->system->handleSegFault(&segFaultHandler)));
|
|
||||||
|
|
||||||
divideByZeroHandler.m = t->m;
|
divideByZeroHandler.m = t->m;
|
||||||
expect(t, t->m->system->success
|
expect(t, signals.registerHandler(SignalRegistrar::DivideByZero, ÷ByZeroHandler));
|
||||||
(t->m->system->handleDivideByZero(÷ByZeroHandler)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void callWithCurrentContinuation(Thread* t, object receiver) {
|
virtual void callWithCurrentContinuation(Thread* t, object receiver) {
|
||||||
@ -9173,6 +9179,7 @@ class MyProcessor: public Processor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
|
SignalRegistrar signals;
|
||||||
Allocator* allocator;
|
Allocator* allocator;
|
||||||
object roots;
|
object roots;
|
||||||
BootImage* bootImage;
|
BootImage* bootImage;
|
||||||
@ -10285,11 +10292,13 @@ codeAllocator(MyThread* t)
|
|||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
Processor*
|
Processor* makeProcessor(System* system,
|
||||||
makeProcessor(System* system, Allocator* allocator, bool useNativeFeatures)
|
Allocator* allocator,
|
||||||
|
const char* crashDumpDirectory,
|
||||||
|
bool useNativeFeatures)
|
||||||
{
|
{
|
||||||
return new (allocator->allocate(sizeof(local::MyProcessor)))
|
return new (allocator->allocate(sizeof(local::MyProcessor)))
|
||||||
local::MyProcessor(system, allocator, useNativeFeatures);
|
local::MyProcessor(system, allocator, crashDumpDirectory, useNativeFeatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include <avian/util/string.h>
|
#include <avian/util/string.h>
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
#include <avian/util/list.h>
|
#include <avian/util/list.h>
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include <avian/vm/heap/heap.h>
|
#include <avian/heap/heap.h>
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include "avian/arch.h"
|
#include "avian/arch.h"
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
|
#include <avian/system/signal.h>
|
||||||
#include "avian/constants.h"
|
#include "avian/constants.h"
|
||||||
#include "avian/machine.h"
|
#include "avian/machine.h"
|
||||||
#include "avian/processor.h"
|
#include "avian/processor.h"
|
||||||
@ -20,6 +21,7 @@
|
|||||||
#include <avian/util/list.h>
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
using namespace avian::system;
|
||||||
|
|
||||||
namespace local {
|
namespace local {
|
||||||
|
|
||||||
@ -2959,9 +2961,11 @@ invoke(Thread* t, object method)
|
|||||||
|
|
||||||
class MyProcessor: public Processor {
|
class MyProcessor: public Processor {
|
||||||
public:
|
public:
|
||||||
MyProcessor(System* s, Allocator* allocator):
|
MyProcessor(System* s, Allocator* allocator, const char* crashDumpDirectory)
|
||||||
s(s), allocator(allocator)
|
: s(s), allocator(allocator)
|
||||||
{ }
|
{
|
||||||
|
signals.setCrashDumpDirectory(crashDumpDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
virtual vm::Thread*
|
virtual vm::Thread*
|
||||||
makeThread(Machine* m, object javaThread, vm::Thread* parent)
|
makeThread(Machine* m, object javaThread, vm::Thread* parent)
|
||||||
@ -3260,21 +3264,25 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
allocator->free(this, sizeof(*this));
|
allocator->free(this, sizeof(*this));
|
||||||
|
signals.setCrashDumpDirectory(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
Allocator* allocator;
|
Allocator* allocator;
|
||||||
|
SignalRegistrar signals;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
Processor*
|
Processor* makeProcessor(System* system,
|
||||||
makeProcessor(System* system, Allocator* allocator, bool)
|
Allocator* allocator,
|
||||||
|
const char* crashDumpDirectory,
|
||||||
|
bool)
|
||||||
{
|
{
|
||||||
return new (allocator->allocate(sizeof(local::MyProcessor)))
|
return new (allocator->allocate(sizeof(local::MyProcessor)))
|
||||||
local::MyProcessor(system, allocator);
|
local::MyProcessor(system, allocator, crashDumpDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -3878,7 +3878,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
|
|
||||||
if (classpath == 0) classpath = ".";
|
if (classpath == 0) classpath = ".";
|
||||||
|
|
||||||
System* s = makeSystem(crashDumpDirectory);
|
System* s = makeSystem();
|
||||||
Heap* h = makeHeap(s, heapLimit);
|
Heap* h = makeHeap(s, heapLimit);
|
||||||
Classpath* c = makeClasspath(s, h, javaHome, embedPrefix);
|
Classpath* c = makeClasspath(s, h, javaHome, embedPrefix);
|
||||||
|
|
||||||
@ -3913,7 +3913,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
Finder* af = makeFinder(s, h, classpath, bootLibrary);
|
Finder* af = makeFinder(s, h, classpath, bootLibrary);
|
||||||
if(bootLibrary)
|
if(bootLibrary)
|
||||||
free(bootLibrary);
|
free(bootLibrary);
|
||||||
Processor* p = makeProcessor(s, h, true);
|
Processor* p = makeProcessor(s, h, crashDumpDirectory, true);
|
||||||
|
|
||||||
const char** properties = static_cast<const char**>
|
const char** properties = static_cast<const char**>
|
||||||
(h->allocate(sizeof(const char*) * propertyCount));
|
(h->allocate(sizeof(const char*) * propertyCount));
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/finder.h"
|
#include "avian/finder.h"
|
||||||
|
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
@ -59,7 +59,7 @@ mainClass(const char* jar)
|
|||||||
{
|
{
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
System* system = makeSystem(0);
|
System* system = makeSystem();
|
||||||
|
|
||||||
class MyAllocator: public Allocator {
|
class MyAllocator: public Allocator {
|
||||||
public:
|
public:
|
||||||
|
@ -49,8 +49,9 @@
|
|||||||
#include "dirent.h"
|
#include "dirent.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include "avian/arch.h"
|
#include "avian/arch.h"
|
||||||
#include <avian/vm/system/system.h>
|
|
||||||
|
|
||||||
|
#include <avian/system/system.h>
|
||||||
|
#include <avian/system/signal.h>
|
||||||
#include <avian/util/math.h>
|
#include <avian/util/math.h>
|
||||||
|
|
||||||
|
|
||||||
@ -78,29 +79,14 @@ class MutexResource {
|
|||||||
const int InvalidSignal = -1;
|
const int InvalidSignal = -1;
|
||||||
const int VisitSignal = SIGUSR1;
|
const int VisitSignal = SIGUSR1;
|
||||||
const unsigned VisitSignalIndex = 0;
|
const unsigned VisitSignalIndex = 0;
|
||||||
const int SegFaultSignal = SIGSEGV;
|
|
||||||
const unsigned SegFaultSignalIndex = 1;
|
|
||||||
const int InterruptSignal = SIGUSR2;
|
const int InterruptSignal = SIGUSR2;
|
||||||
const unsigned InterruptSignalIndex = 2;
|
const unsigned InterruptSignalIndex = 1;
|
||||||
#ifdef __APPLE__
|
|
||||||
const int AltSegFaultSignal = SIGBUS;
|
|
||||||
#else
|
|
||||||
const int AltSegFaultSignal = InvalidSignal;
|
|
||||||
#endif
|
|
||||||
const unsigned AltSegFaultSignalIndex = 3;
|
|
||||||
const int PipeSignal = SIGPIPE;
|
const int PipeSignal = SIGPIPE;
|
||||||
const unsigned PipeSignalIndex = 4;
|
const unsigned PipeSignalIndex = 2;
|
||||||
const int DivideByZeroSignal = SIGFPE;
|
|
||||||
const unsigned DivideByZeroSignalIndex = 5;
|
|
||||||
|
|
||||||
const int signals[] = { VisitSignal,
|
const int signals[] = {VisitSignal, InterruptSignal, PipeSignal};
|
||||||
SegFaultSignal,
|
|
||||||
InterruptSignal,
|
|
||||||
AltSegFaultSignal,
|
|
||||||
PipeSignal,
|
|
||||||
DivideByZeroSignal };
|
|
||||||
|
|
||||||
const unsigned SignalCount = 6;
|
const unsigned SignalCount = 3;
|
||||||
|
|
||||||
class MySystem;
|
class MySystem;
|
||||||
MySystem* system;
|
MySystem* system;
|
||||||
@ -123,7 +109,7 @@ pathOfExecutable(System* s, const char** retBuf, unsigned* size)
|
|||||||
CFURLRef url = CFBundleCopyExecutableURL(bundle);
|
CFURLRef url = CFBundleCopyExecutableURL(bundle);
|
||||||
CFStringRef path = CFURLCopyPath(url);
|
CFStringRef path = CFURLCopyPath(url);
|
||||||
path = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault,
|
path = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault,
|
||||||
path, CFSTR(""));
|
path, CFSTR(""));
|
||||||
CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
|
CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
|
||||||
char* buffer = reinterpret_cast<char*>(allocate(s, pathSize));
|
char* buffer = reinterpret_cast<char*>(allocate(s, pathSize));
|
||||||
if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) {
|
if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) {
|
||||||
@ -606,32 +592,27 @@ class MySystem: public System {
|
|||||||
expect(this, system == 0);
|
expect(this, system == 0);
|
||||||
system = this;
|
system = this;
|
||||||
|
|
||||||
memset(handlers, 0, sizeof(handlers));
|
expect(this, registerHandler(InterruptSignalIndex));
|
||||||
|
expect(this, registerHandler(VisitSignalIndex));
|
||||||
registerHandler(&nullHandler, InterruptSignalIndex);
|
expect(this, registerHandler(PipeSignalIndex));
|
||||||
registerHandler(&nullHandler, PipeSignalIndex);
|
|
||||||
registerHandler(&nullHandler, VisitSignalIndex);
|
|
||||||
|
|
||||||
expect(this, make(&visitLock) == 0);
|
expect(this, make(&visitLock) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int registerHandler(System::SignalHandler* handler, int index) {
|
// Returns true on success, false on failure
|
||||||
if (handler) {
|
bool unregisterHandler(int index) {
|
||||||
handlers[index] = handler;
|
return sigaction(signals[index], oldHandlers + index, 0) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct sigaction sa;
|
// Returns true on success, false on failure
|
||||||
memset(&sa, 0, sizeof(struct sigaction));
|
bool registerHandler(int index) {
|
||||||
sigemptyset(&(sa.sa_mask));
|
struct sigaction sa;
|
||||||
sa.sa_flags = SA_SIGINFO;
|
memset(&sa, 0, sizeof(struct sigaction));
|
||||||
sa.sa_sigaction = handleSignal;
|
sigemptyset(&(sa.sa_mask));
|
||||||
|
sa.sa_flags = SA_SIGINFO;
|
||||||
return sigaction(signals[index], &sa, oldHandlers + index);
|
sa.sa_sigaction = handleSignal;
|
||||||
} else if (handlers[index]) {
|
|
||||||
handlers[index] = 0;
|
return sigaction(signals[index], &sa, oldHandlers + index) == 0;
|
||||||
return sigaction(signals[index], oldHandlers + index, 0);
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned sizeInBytes) {
|
virtual void* tryAllocate(unsigned sizeInBytes) {
|
||||||
@ -701,18 +682,6 @@ class MySystem: public System {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Status handleSegFault(SignalHandler* handler) {
|
|
||||||
Status s = registerHandler(handler, SegFaultSignalIndex);
|
|
||||||
if (s == 0 and AltSegFaultSignal != InvalidSignal) {
|
|
||||||
return registerHandler(handler, AltSegFaultSignalIndex);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Status handleDivideByZero(SignalHandler* handler) {
|
|
||||||
return registerHandler(handler, DivideByZeroSignalIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
|
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
|
||||||
ThreadVisitor* visitor)
|
ThreadVisitor* visitor)
|
||||||
{
|
{
|
||||||
@ -931,25 +900,20 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void abort() {
|
virtual void abort() {
|
||||||
::abort();
|
avian::system::crash();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
visitLock->dispose();
|
visitLock->dispose();
|
||||||
|
|
||||||
registerHandler(0, InterruptSignalIndex);
|
expect(this, unregisterHandler(InterruptSignalIndex));
|
||||||
registerHandler(0, VisitSignalIndex);
|
expect(this, unregisterHandler(VisitSignalIndex));
|
||||||
registerHandler(0, PipeSignalIndex);
|
expect(this, unregisterHandler(PipeSignalIndex));
|
||||||
system = 0;
|
system = 0;
|
||||||
|
|
||||||
::free(this);
|
::free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NullSignalHandler: public SignalHandler {
|
|
||||||
virtual bool handleSignal(void**, void**, void**, void**) { return false; }
|
|
||||||
} nullHandler;
|
|
||||||
|
|
||||||
SignalHandler* handlers[SignalCount];
|
|
||||||
struct sigaction oldHandlers[SignalCount];
|
struct sigaction oldHandlers[SignalCount];
|
||||||
|
|
||||||
ThreadVisitor* threadVisitor;
|
ThreadVisitor* threadVisitor;
|
||||||
@ -957,27 +921,16 @@ class MySystem: public System {
|
|||||||
System::Monitor* visitLock;
|
System::Monitor* visitLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void handleSignal(int signal, siginfo_t*, void* context)
|
||||||
handleSignal(int signal, siginfo_t*, void* context)
|
|
||||||
{
|
{
|
||||||
ucontext_t* c = static_cast<ucontext_t*>(context);
|
ucontext_t* c = static_cast<ucontext_t*>(context);
|
||||||
|
|
||||||
void* ip = reinterpret_cast<void*>(IP_REGISTER(c));
|
void* ip = reinterpret_cast<void*>(IP_REGISTER(c));
|
||||||
void* stack = reinterpret_cast<void*>(STACK_REGISTER(c));
|
void* stack = reinterpret_cast<void*>(STACK_REGISTER(c));
|
||||||
void* thread = reinterpret_cast<void*>(THREAD_REGISTER(c));
|
|
||||||
void* link = reinterpret_cast<void*>(LINK_REGISTER(c));
|
void* link = reinterpret_cast<void*>(LINK_REGISTER(c));
|
||||||
#ifdef FRAME_REGISTER
|
|
||||||
void* frame = reinterpret_cast<void*>(FRAME_REGISTER(c));
|
|
||||||
#else
|
|
||||||
void* frame = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned index;
|
|
||||||
|
|
||||||
switch (signal) {
|
switch (signal) {
|
||||||
case VisitSignal: {
|
case VisitSignal: {
|
||||||
index = VisitSignalIndex;
|
|
||||||
|
|
||||||
system->threadVisitor->visit(ip, stack, link);
|
system->threadVisitor->visit(ip, stack, link);
|
||||||
|
|
||||||
System::Thread* t = system->visitTarget;
|
System::Thread* t = system->visitTarget;
|
||||||
@ -987,57 +940,6 @@ handleSignal(int signal, siginfo_t*, void* context)
|
|||||||
system->visitLock->notifyAll(t);
|
system->visitLock->notifyAll(t);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SegFaultSignal:
|
|
||||||
case AltSegFaultSignal:
|
|
||||||
case DivideByZeroSignal: {
|
|
||||||
switch (signal) {
|
|
||||||
case SegFaultSignal:
|
|
||||||
index = SegFaultSignalIndex;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AltSegFaultSignal:
|
|
||||||
index = AltSegFaultSignalIndex;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DivideByZeroSignal:
|
|
||||||
index = DivideByZeroSignalIndex;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool jump = system->handlers[index]->handleSignal
|
|
||||||
(&ip, &frame, &stack, &thread);
|
|
||||||
|
|
||||||
if (jump) {
|
|
||||||
// I'd like to use setcontext here (and get rid of the
|
|
||||||
// sigprocmask call), but it doesn't work on my Linux x86_64
|
|
||||||
// system, and I can't tell from the documentation if it's even
|
|
||||||
// supposed to work.
|
|
||||||
|
|
||||||
sigset_t set;
|
|
||||||
sigemptyset(&set);
|
|
||||||
sigaddset(&set, signal);
|
|
||||||
pthread_sigmask(SIG_UNBLOCK, &set, 0);
|
|
||||||
|
|
||||||
vmJump(ip, frame, stack, thread, 0, 0);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case InterruptSignal: {
|
|
||||||
index = InterruptSignalIndex;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case PipeSignal: {
|
|
||||||
index = PipeSignalIndex;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (signal) {
|
|
||||||
case VisitSignal:
|
|
||||||
case InterruptSignal:
|
case InterruptSignal:
|
||||||
case PipeSignal:
|
case PipeSignal:
|
||||||
break;
|
break;
|
||||||
@ -1052,7 +954,7 @@ handleSignal(int signal, siginfo_t*, void* context)
|
|||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
AVIAN_EXPORT System*
|
AVIAN_EXPORT System*
|
||||||
makeSystem(const char*)
|
makeSystem()
|
||||||
{
|
{
|
||||||
return new (malloc(sizeof(MySystem))) MySystem();
|
return new (malloc(sizeof(MySystem))) MySystem();
|
||||||
}
|
}
|
233
src/system/posix/signal.cpp
Normal file
233
src/system/posix/signal.cpp
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/* Copyright (c) 2008-2013, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "signal.h"
|
||||||
|
#include "sys/types.h"
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
|
#include "sys/ucontext.h"
|
||||||
|
#undef assert
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
#include <asm/sigcontext.h> /* for sigcontext */
|
||||||
|
#include <asm/signal.h> /* for stack_t */
|
||||||
|
typedef struct ucontext {
|
||||||
|
unsigned long uc_flags;
|
||||||
|
struct ucontext* uc_link;
|
||||||
|
stack_t uc_stack;
|
||||||
|
struct sigcontext uc_mcontext;
|
||||||
|
unsigned long uc_sigmask;
|
||||||
|
} ucontext_t;
|
||||||
|
#else
|
||||||
|
#if defined __FreeBSD__
|
||||||
|
#include "limits.h"
|
||||||
|
#endif
|
||||||
|
#include "ucontext.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "avian/arch.h"
|
||||||
|
#include <avian/system/system.h>
|
||||||
|
#include <avian/system/signal.h>
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
namespace posix {
|
||||||
|
|
||||||
|
|
||||||
|
const int InvalidSignal = -1;
|
||||||
|
const int SegFaultSignal = SIGSEGV;
|
||||||
|
const unsigned SegFaultSignalIndex = 0;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const int AltSegFaultSignal = SIGBUS;
|
||||||
|
#else
|
||||||
|
const int AltSegFaultSignal = InvalidSignal;
|
||||||
|
#endif
|
||||||
|
const unsigned AltSegFaultSignalIndex = 1;
|
||||||
|
const int DivideByZeroSignal = SIGFPE;
|
||||||
|
const unsigned DivideByZeroSignalIndex = 2;
|
||||||
|
|
||||||
|
const int signals[]
|
||||||
|
= {SegFaultSignal, AltSegFaultSignal, DivideByZeroSignal};
|
||||||
|
|
||||||
|
const unsigned SignalCount = 3;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SignalRegistrar::Data {
|
||||||
|
Handler* handlers[posix::SignalCount];
|
||||||
|
struct sigaction oldHandlers[posix::SignalCount];
|
||||||
|
|
||||||
|
bool registerHandler(Handler* handler, int index);
|
||||||
|
|
||||||
|
Data()
|
||||||
|
{
|
||||||
|
if(instance) {
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Data()
|
||||||
|
{
|
||||||
|
instance = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SignalRegistrar::Data* instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
SignalRegistrar::Data* SignalRegistrar::Data::instance = 0;
|
||||||
|
|
||||||
|
namespace posix {
|
||||||
|
|
||||||
|
using namespace vm;
|
||||||
|
|
||||||
|
void handleSignal(int signal, siginfo_t*, void* context)
|
||||||
|
{
|
||||||
|
ucontext_t* c = static_cast<ucontext_t*>(context);
|
||||||
|
|
||||||
|
void* ip = reinterpret_cast<void*>(IP_REGISTER(c));
|
||||||
|
void* stack = reinterpret_cast<void*>(STACK_REGISTER(c));
|
||||||
|
void* thread = reinterpret_cast<void*>(THREAD_REGISTER(c));
|
||||||
|
#ifdef FRAME_REGISTER
|
||||||
|
void* frame = reinterpret_cast<void*>(FRAME_REGISTER(c));
|
||||||
|
#else
|
||||||
|
void* frame = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
switch (signal) {
|
||||||
|
case SegFaultSignal:
|
||||||
|
case AltSegFaultSignal:
|
||||||
|
case DivideByZeroSignal: {
|
||||||
|
switch (signal) {
|
||||||
|
case SegFaultSignal:
|
||||||
|
index = SegFaultSignalIndex;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AltSegFaultSignal:
|
||||||
|
index = AltSegFaultSignalIndex;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DivideByZeroSignal:
|
||||||
|
index = DivideByZeroSignalIndex;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool jump
|
||||||
|
= SignalRegistrar::Data::instance->handlers[index]->handleSignal(&ip, &frame, &stack, &thread);
|
||||||
|
|
||||||
|
if (jump) {
|
||||||
|
// I'd like to use setcontext here (and get rid of the
|
||||||
|
// sigprocmask call), but it doesn't work on my Linux x86_64
|
||||||
|
// system, and I can't tell from the documentation if it's even
|
||||||
|
// supposed to work.
|
||||||
|
|
||||||
|
sigset_t set;
|
||||||
|
sigemptyset(&set);
|
||||||
|
sigaddset(&set, signal);
|
||||||
|
pthread_sigmask(SIG_UNBLOCK, &set, 0);
|
||||||
|
|
||||||
|
vmJump(ip, frame, stack, thread, 0, 0);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace posix
|
||||||
|
|
||||||
|
NO_RETURN void crash()
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalRegistrar::SignalRegistrar()
|
||||||
|
{
|
||||||
|
data = new (malloc(sizeof(Data))) Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalRegistrar::~SignalRegistrar()
|
||||||
|
{
|
||||||
|
data->~Data();
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalRegistrar::Data::registerHandler(Handler* handler, int index)
|
||||||
|
{
|
||||||
|
if (handler) {
|
||||||
|
handlers[index] = handler;
|
||||||
|
|
||||||
|
struct sigaction sa;
|
||||||
|
memset(&sa, 0, sizeof(struct sigaction));
|
||||||
|
sigemptyset(&(sa.sa_mask));
|
||||||
|
sa.sa_flags = SA_SIGINFO;
|
||||||
|
sa.sa_sigaction = posix::handleSignal;
|
||||||
|
|
||||||
|
return sigaction(posix::signals[index], &sa, oldHandlers + index) == 0;
|
||||||
|
} else if (handlers[index]) {
|
||||||
|
handlers[index] = 0;
|
||||||
|
return sigaction(posix::signals[index], oldHandlers + index, 0) == 0;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalRegistrar::registerHandler(Signal signal, Handler* handler)
|
||||||
|
{
|
||||||
|
switch(signal) {
|
||||||
|
case SegFault:
|
||||||
|
if(!data->registerHandler(handler, posix::SegFaultSignalIndex)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (posix::AltSegFaultSignal != posix::InvalidSignal) {
|
||||||
|
return data->registerHandler(handler, posix::AltSegFaultSignalIndex);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case DivideByZero:
|
||||||
|
return data->registerHandler(handler, posix::DivideByZeroSignalIndex);
|
||||||
|
default:
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalRegistrar::unregisterHandler(Signal signal)
|
||||||
|
{
|
||||||
|
switch(signal) {
|
||||||
|
case SegFault:
|
||||||
|
if(!data->registerHandler(0, posix::SegFaultSignalIndex)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (posix::AltSegFaultSignal != posix::InvalidSignal) {
|
||||||
|
return data->registerHandler(0, posix::AltSegFaultSignalIndex);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case DivideByZero:
|
||||||
|
return data->registerHandler(0, posix::DivideByZeroSignalIndex);
|
||||||
|
default:
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalRegistrar::setCrashDumpDirectory(const char*)
|
||||||
|
{
|
||||||
|
// Do nothing, not currently supported on posix
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace system
|
||||||
|
} // namespace avian
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include "sys/stat.h"
|
#include "sys/stat.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "sys/timeb.h"
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define S_ISREG(x) ((x) & _S_IFREG)
|
# define S_ISREG(x) ((x) & _S_IFREG)
|
||||||
@ -24,7 +23,8 @@
|
|||||||
#undef min
|
#undef min
|
||||||
|
|
||||||
#include "avian/arch.h"
|
#include "avian/arch.h"
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
|
#include <avian/system/signal.h>
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
|
|
||||||
#if defined(WINAPI_FAMILY)
|
#if defined(WINAPI_FAMILY)
|
||||||
@ -115,11 +115,6 @@ class MutexResource {
|
|||||||
HANDLE m;
|
HANDLE m;
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned SegFaultIndex = 0;
|
|
||||||
const unsigned DivideByZeroIndex = 1;
|
|
||||||
|
|
||||||
const unsigned HandlerCount = 2;
|
|
||||||
|
|
||||||
class MySystem;
|
class MySystem;
|
||||||
MySystem* system;
|
MySystem* system;
|
||||||
|
|
||||||
@ -626,68 +621,15 @@ class MySystem: public System {
|
|||||||
System::Library* next_;
|
System::Library* next_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MySystem(const char* crashDumpDirectory):
|
MySystem()
|
||||||
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
oldHandler(0),
|
|
||||||
#endif
|
|
||||||
crashDumpDirectory(crashDumpDirectory)
|
|
||||||
{
|
{
|
||||||
expect(this, system == 0);
|
expect(this, system == 0);
|
||||||
system = this;
|
system = this;
|
||||||
|
|
||||||
memset(handlers, 0, sizeof(handlers));
|
|
||||||
|
|
||||||
mutex = CreateMutex(0, false, 0);
|
mutex = CreateMutex(0, false, 0);
|
||||||
assert(this, mutex);
|
assert(this, mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findHandler() {
|
|
||||||
for (unsigned i = 0; i < HandlerCount; ++i) {
|
|
||||||
if (handlers[i]) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int registerHandler(System::SignalHandler* handler, int index) {
|
|
||||||
if (handler) {
|
|
||||||
handlers[index] = handler;
|
|
||||||
|
|
||||||
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
if (oldHandler == 0) {
|
|
||||||
# ifdef ARCH_x86_32
|
|
||||||
oldHandler = SetUnhandledExceptionFilter(handleException);
|
|
||||||
# elif defined ARCH_x86_64
|
|
||||||
AddVectoredExceptionHandler(1, handleException);
|
|
||||||
oldHandler = reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(1);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#pragma message("TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else if (handlers[index]) {
|
|
||||||
handlers[index] = 0;
|
|
||||||
|
|
||||||
if (not findHandler()) {
|
|
||||||
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
# ifdef ARCH_x86_32
|
|
||||||
SetUnhandledExceptionFilter(oldHandler);
|
|
||||||
oldHandler = 0;
|
|
||||||
# elif defined ARCH_x86_64
|
|
||||||
// do nothing, handlers are never "unregistered" anyway
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
#pragma message("TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned sizeInBytes) {
|
virtual void* tryAllocate(unsigned sizeInBytes) {
|
||||||
return malloc(sizeInBytes);
|
return malloc(sizeInBytes);
|
||||||
}
|
}
|
||||||
@ -746,14 +688,6 @@ class MySystem: public System {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Status handleSegFault(SignalHandler* handler) {
|
|
||||||
return registerHandler(handler, SegFaultIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Status handleDivideByZero(SignalHandler* handler) {
|
|
||||||
return registerHandler(handler, DivideByZeroIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
|
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
|
||||||
ThreadVisitor* visitor)
|
ThreadVisitor* visitor)
|
||||||
{
|
{
|
||||||
@ -1008,9 +942,7 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void abort() {
|
virtual void abort() {
|
||||||
// trigger an EXCEPTION_ACCESS_VIOLATION, which we will catch and
|
avian::system::crash();
|
||||||
// generate a debug dump for
|
|
||||||
*static_cast<volatile int*>(0) = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
@ -1020,139 +952,16 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HANDLE mutex;
|
HANDLE mutex;
|
||||||
SignalHandler* handlers[HandlerCount];
|
|
||||||
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
|
|
||||||
#endif
|
|
||||||
const char* crashDumpDirectory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
|
|
||||||
#pragma pack(push,4)
|
|
||||||
struct MINIDUMP_EXCEPTION_INFORMATION {
|
|
||||||
DWORD thread;
|
|
||||||
LPEXCEPTION_POINTERS exception;
|
|
||||||
BOOL exceptionInCurrentAddressSpace;
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
struct MINIDUMP_USER_STREAM_INFORMATION;
|
|
||||||
struct MINIDUMP_CALLBACK_INFORMATION;
|
|
||||||
|
|
||||||
enum MINIDUMP_TYPE {
|
|
||||||
MiniDumpNormal = 0,
|
|
||||||
MiniDumpWithFullMemory = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BOOL (*MiniDumpWriteDumpType)
|
|
||||||
(HANDLE processHandle,
|
|
||||||
DWORD processId,
|
|
||||||
HANDLE file,
|
|
||||||
MINIDUMP_TYPE type,
|
|
||||||
const MINIDUMP_EXCEPTION_INFORMATION* exception,
|
|
||||||
const MINIDUMP_USER_STREAM_INFORMATION* userStream,
|
|
||||||
const MINIDUMP_CALLBACK_INFORMATION* callback);
|
|
||||||
|
|
||||||
void
|
|
||||||
dump(LPEXCEPTION_POINTERS e, const char* directory)
|
|
||||||
{
|
|
||||||
HINSTANCE dbghelp = LoadLibrary("dbghelp.dll");
|
|
||||||
|
|
||||||
if (dbghelp) {
|
|
||||||
MiniDumpWriteDumpType MiniDumpWriteDump = reinterpret_cast
|
|
||||||
<MiniDumpWriteDumpType>(GetProcAddress(dbghelp, "MiniDumpWriteDump"));
|
|
||||||
|
|
||||||
if (MiniDumpWriteDump) {
|
|
||||||
char name[MAX_PATH];
|
|
||||||
_timeb tb;
|
|
||||||
FTIME(&tb);
|
|
||||||
vm::snprintf(name, MAX_PATH, "%s\\crash-%" LLD ".mdmp", directory,
|
|
||||||
(static_cast<int64_t>(tb.time) * 1000)
|
|
||||||
+ static_cast<int64_t>(tb.millitm));
|
|
||||||
|
|
||||||
HANDLE file = CreateFile
|
|
||||||
(name, FILE_WRITE_DATA, 0, 0, CREATE_ALWAYS, 0, 0);
|
|
||||||
|
|
||||||
if (file != INVALID_HANDLE_VALUE) {
|
|
||||||
MINIDUMP_EXCEPTION_INFORMATION exception
|
|
||||||
= { GetCurrentThreadId(), e, true };
|
|
||||||
|
|
||||||
MiniDumpWriteDump
|
|
||||||
(GetCurrentProcess(),
|
|
||||||
GetCurrentProcessId(),
|
|
||||||
file,
|
|
||||||
MiniDumpWithFullMemory,
|
|
||||||
&exception,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
|
|
||||||
CloseHandle(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeLibrary(dbghelp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LONG CALLBACK
|
|
||||||
handleException(LPEXCEPTION_POINTERS e)
|
|
||||||
{
|
|
||||||
System::SignalHandler* handler = 0;
|
|
||||||
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
|
||||||
handler = system->handlers[SegFaultIndex];
|
|
||||||
} else if (e->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
|
|
||||||
{
|
|
||||||
handler = system->handlers[DivideByZeroIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler) {
|
|
||||||
#ifdef ARCH_x86_32
|
|
||||||
void* ip = reinterpret_cast<void*>(e->ContextRecord->Eip);
|
|
||||||
void* base = reinterpret_cast<void*>(e->ContextRecord->Ebp);
|
|
||||||
void* stack = reinterpret_cast<void*>(e->ContextRecord->Esp);
|
|
||||||
void* thread = reinterpret_cast<void*>(e->ContextRecord->Ebx);
|
|
||||||
#elif defined ARCH_x86_64
|
|
||||||
void* ip = reinterpret_cast<void*>(e->ContextRecord->Rip);
|
|
||||||
void* base = reinterpret_cast<void*>(e->ContextRecord->Rbp);
|
|
||||||
void* stack = reinterpret_cast<void*>(e->ContextRecord->Rsp);
|
|
||||||
void* thread = reinterpret_cast<void*>(e->ContextRecord->Rbx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool jump = handler->handleSignal(&ip, &base, &stack, &thread);
|
|
||||||
|
|
||||||
#ifdef ARCH_x86_32
|
|
||||||
e->ContextRecord->Eip = reinterpret_cast<DWORD>(ip);
|
|
||||||
e->ContextRecord->Ebp = reinterpret_cast<DWORD>(base);
|
|
||||||
e->ContextRecord->Esp = reinterpret_cast<DWORD>(stack);
|
|
||||||
e->ContextRecord->Ebx = reinterpret_cast<DWORD>(thread);
|
|
||||||
#elif defined ARCH_x86_64
|
|
||||||
e->ContextRecord->Rip = reinterpret_cast<DWORD64>(ip);
|
|
||||||
e->ContextRecord->Rbp = reinterpret_cast<DWORD64>(base);
|
|
||||||
e->ContextRecord->Rsp = reinterpret_cast<DWORD64>(stack);
|
|
||||||
e->ContextRecord->Rbx = reinterpret_cast<DWORD64>(thread);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (jump) {
|
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
|
||||||
} else if (system->crashDumpDirectory) {
|
|
||||||
dump(e, system->crashDumpDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
AVIAN_EXPORT System*
|
AVIAN_EXPORT System*
|
||||||
makeSystem(const char* crashDumpDirectory)
|
makeSystem()
|
||||||
{
|
{
|
||||||
return new (malloc(sizeof(MySystem))) MySystem(crashDumpDirectory);
|
return new (malloc(sizeof(MySystem))) MySystem();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
292
src/system/windows/signal.cpp
Normal file
292
src/system/windows/signal.cpp
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
/* Copyright (c) 2008-2013, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "windows.h"
|
||||||
|
#include "sys/timeb.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define FTIME _ftime_s
|
||||||
|
#else
|
||||||
|
#define FTIME _ftime
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WINAPI_FAMILY
|
||||||
|
|
||||||
|
#ifndef WINAPI_PARTITION_DESKTOP
|
||||||
|
#define WINAPI_PARTITION_DESKTOP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WINAPI_FAMILY_PARTITION
|
||||||
|
#define WINAPI_FAMILY_PARTITION(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <avian/system/signal.h>
|
||||||
|
#include <avian/common.h>
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
namespace windows {
|
||||||
|
|
||||||
|
const unsigned HandlerCount = 2;
|
||||||
|
|
||||||
|
} // namespace windows
|
||||||
|
|
||||||
|
struct SignalRegistrar::Data {
|
||||||
|
Handler* handlers[windows::HandlerCount];
|
||||||
|
const char* crashDumpDirectory;
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Data() : crashDumpDirectory(0),
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
oldHandler(0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (instance) {
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
instance = this;
|
||||||
|
memset(handlers, 0, sizeof(handlers));
|
||||||
|
}
|
||||||
|
|
||||||
|
~Data()
|
||||||
|
{
|
||||||
|
instance = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool registerHandler(Handler* handler, int index);
|
||||||
|
|
||||||
|
bool findHandler() {
|
||||||
|
for (unsigned i = 0; i < windows::HandlerCount; ++i) {
|
||||||
|
if (handlers[i]) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SignalRegistrar::Data* instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
SignalRegistrar::Data* SignalRegistrar::Data::instance = 0;
|
||||||
|
|
||||||
|
namespace windows {
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
|
||||||
|
#pragma pack(push, 4)
|
||||||
|
struct MINIDUMP_EXCEPTION_INFORMATION {
|
||||||
|
DWORD thread;
|
||||||
|
LPEXCEPTION_POINTERS exception;
|
||||||
|
BOOL exceptionInCurrentAddressSpace;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct MINIDUMP_USER_STREAM_INFORMATION;
|
||||||
|
struct MINIDUMP_CALLBACK_INFORMATION;
|
||||||
|
|
||||||
|
enum MINIDUMP_TYPE {
|
||||||
|
MiniDumpNormal = 0,
|
||||||
|
MiniDumpWithFullMemory = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BOOL (*MiniDumpWriteDumpType)(HANDLE processHandle,
|
||||||
|
DWORD processId,
|
||||||
|
HANDLE file,
|
||||||
|
MINIDUMP_TYPE type,
|
||||||
|
const MINIDUMP_EXCEPTION_INFORMATION
|
||||||
|
* exception,
|
||||||
|
const MINIDUMP_USER_STREAM_INFORMATION
|
||||||
|
* userStream,
|
||||||
|
const MINIDUMP_CALLBACK_INFORMATION
|
||||||
|
* callback);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void dump(LPEXCEPTION_POINTERS e, const char* directory)
|
||||||
|
{
|
||||||
|
HINSTANCE dbghelp = LoadLibrary("dbghelp.dll");
|
||||||
|
|
||||||
|
if (dbghelp) {
|
||||||
|
MiniDumpWriteDumpType MiniDumpWriteDump = reinterpret_cast
|
||||||
|
<MiniDumpWriteDumpType>(GetProcAddress(dbghelp, "MiniDumpWriteDump"));
|
||||||
|
|
||||||
|
if (MiniDumpWriteDump) {
|
||||||
|
char name[MAX_PATH];
|
||||||
|
_timeb tb;
|
||||||
|
FTIME(&tb);
|
||||||
|
vm::snprintf(name,
|
||||||
|
MAX_PATH,
|
||||||
|
"%s\\crash-%" LLD ".mdmp",
|
||||||
|
directory,
|
||||||
|
(static_cast<int64_t>(tb.time) * 1000) + static_cast
|
||||||
|
<int64_t>(tb.millitm));
|
||||||
|
|
||||||
|
HANDLE file
|
||||||
|
= CreateFile(name, FILE_WRITE_DATA, 0, 0, CREATE_ALWAYS, 0, 0);
|
||||||
|
|
||||||
|
if (file != INVALID_HANDLE_VALUE) {
|
||||||
|
MINIDUMP_EXCEPTION_INFORMATION exception
|
||||||
|
= {GetCurrentThreadId(), e, true};
|
||||||
|
|
||||||
|
MiniDumpWriteDump(GetCurrentProcess(),
|
||||||
|
GetCurrentProcessId(),
|
||||||
|
file,
|
||||||
|
MiniDumpWithFullMemory,
|
||||||
|
&exception,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
|
||||||
|
CloseHandle(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeLibrary(dbghelp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG CALLBACK handleException(LPEXCEPTION_POINTERS e)
|
||||||
|
{
|
||||||
|
SignalRegistrar::Handler* handler = 0;
|
||||||
|
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||||
|
handler = SignalRegistrar::Data::instance->handlers[SignalRegistrar::SegFault];
|
||||||
|
} else if (e->ExceptionRecord->ExceptionCode
|
||||||
|
== EXCEPTION_INT_DIVIDE_BY_ZERO) {
|
||||||
|
handler = SignalRegistrar::Data::instance->handlers[SignalRegistrar::DivideByZero];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler) {
|
||||||
|
#ifdef ARCH_x86_32
|
||||||
|
void* ip = reinterpret_cast<void*>(e->ContextRecord->Eip);
|
||||||
|
void* base = reinterpret_cast<void*>(e->ContextRecord->Ebp);
|
||||||
|
void* stack = reinterpret_cast<void*>(e->ContextRecord->Esp);
|
||||||
|
void* thread = reinterpret_cast<void*>(e->ContextRecord->Ebx);
|
||||||
|
#elif defined ARCH_x86_64
|
||||||
|
void* ip = reinterpret_cast<void*>(e->ContextRecord->Rip);
|
||||||
|
void* base = reinterpret_cast<void*>(e->ContextRecord->Rbp);
|
||||||
|
void* stack = reinterpret_cast<void*>(e->ContextRecord->Rsp);
|
||||||
|
void* thread = reinterpret_cast<void*>(e->ContextRecord->Rbx);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool jump = handler->handleSignal(&ip, &base, &stack, &thread);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86_32
|
||||||
|
e->ContextRecord->Eip = reinterpret_cast<DWORD>(ip);
|
||||||
|
e->ContextRecord->Ebp = reinterpret_cast<DWORD>(base);
|
||||||
|
e->ContextRecord->Esp = reinterpret_cast<DWORD>(stack);
|
||||||
|
e->ContextRecord->Ebx = reinterpret_cast<DWORD>(thread);
|
||||||
|
#elif defined ARCH_x86_64
|
||||||
|
e->ContextRecord->Rip = reinterpret_cast<DWORD64>(ip);
|
||||||
|
e->ContextRecord->Rbp = reinterpret_cast<DWORD64>(base);
|
||||||
|
e->ContextRecord->Rsp = reinterpret_cast<DWORD64>(stack);
|
||||||
|
e->ContextRecord->Rbx = reinterpret_cast<DWORD64>(thread);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (jump) {
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
} else if (SignalRegistrar::Data::instance->crashDumpDirectory) {
|
||||||
|
dump(e, SignalRegistrar::Data::instance->crashDumpDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace windows
|
||||||
|
|
||||||
|
SignalRegistrar::SignalRegistrar()
|
||||||
|
{
|
||||||
|
data = new (malloc(sizeof(Data))) Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalRegistrar::~SignalRegistrar()
|
||||||
|
{
|
||||||
|
data->~Data();
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalRegistrar::Data::registerHandler(Handler* handler, int index)
|
||||||
|
{
|
||||||
|
if(index != SegFault && index != DivideByZero) {
|
||||||
|
crash();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler) {
|
||||||
|
handlers[index] = handler;
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
if (oldHandler == 0) {
|
||||||
|
#ifdef ARCH_x86_32
|
||||||
|
oldHandler = SetUnhandledExceptionFilter(windows::handleException);
|
||||||
|
#elif defined ARCH_x86_64
|
||||||
|
AddVectoredExceptionHandler(1, windows::handleException);
|
||||||
|
oldHandler = reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#pragma message( \
|
||||||
|
"TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (handlers[index]) {
|
||||||
|
handlers[index] = 0;
|
||||||
|
|
||||||
|
if (not findHandler()) {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
#ifdef ARCH_x86_32
|
||||||
|
SetUnhandledExceptionFilter(oldHandler);
|
||||||
|
oldHandler = 0;
|
||||||
|
#elif defined ARCH_x86_64
|
||||||
|
// do nothing, handlers are never "unregistered" anyway
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#pragma message( \
|
||||||
|
"TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NO_RETURN void crash()
|
||||||
|
{
|
||||||
|
// trigger an EXCEPTION_ACCESS_VIOLATION, which we will catch and
|
||||||
|
// generate a debug dump for
|
||||||
|
*static_cast<volatile int*>(0) = 0;
|
||||||
|
|
||||||
|
// Some (all?) compilers don't realize that we can't possibly continue past
|
||||||
|
// the above statement.
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalRegistrar::registerHandler(Signal signal, Handler* handler)
|
||||||
|
{
|
||||||
|
return data->registerHandler(handler, signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalRegistrar::unregisterHandler(Signal signal)
|
||||||
|
{
|
||||||
|
return data->registerHandler(0, signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalRegistrar::setCrashDumpDirectory(const char* crashDumpDirectory)
|
||||||
|
{
|
||||||
|
data->crashDumpDirectory = crashDumpDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace system
|
||||||
|
} // namespace avian
|
@ -8,16 +8,16 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
|
|
||||||
#include <avian/util/arg-parser.h>
|
#include <avian/util/arg-parser.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/targets.h>
|
#include <avian/codegen/targets.h>
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
|
|
||||||
#include <avian/vm/heap/heap.h>
|
#include <avian/heap/heap.h>
|
||||||
|
|
||||||
// since we aren't linking against libstdc++, we must implement this
|
// since we aren't linking against libstdc++, we must implement this
|
||||||
// ourselves:
|
// ourselves:
|
||||||
@ -34,7 +34,7 @@ public:
|
|||||||
Architecture* arch;
|
Architecture* arch;
|
||||||
|
|
||||||
BasicEnv():
|
BasicEnv():
|
||||||
s(makeSystem(0)),
|
s(makeSystem()),
|
||||||
heap(makeHeap(s, 32 * 1024)),
|
heap(makeHeap(s, 32 * 1024)),
|
||||||
arch(makeArchitectureNative(s, true))
|
arch(makeArchitectureNative(s, true))
|
||||||
{
|
{
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include <avian/vm/heap/heap.h>
|
#include <avian/heap/heap.h>
|
||||||
#include "avian/heapwalk.h"
|
#include "avian/heapwalk.h"
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include "avian/machine.h"
|
#include "avian/machine.h"
|
||||||
#include "avian/util.h"
|
#include "avian/util.h"
|
||||||
#include <avian/util/stream.h>
|
#include <avian/util/stream.h>
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/promise.h>
|
#include <avian/codegen/promise.h>
|
||||||
#include "avian/target.h"
|
#include "avian/target.h"
|
||||||
#include <avian/tools/object-writer/tools.h>
|
#include <avian/tools/object-writer/tools.h>
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
@ -1899,11 +1899,11 @@ main(int ac, const char** av)
|
|||||||
Arguments args(ac, av);
|
Arguments args(ac, av);
|
||||||
// args.dump();
|
// args.dump();
|
||||||
|
|
||||||
System* s = makeSystem(0);
|
System* s = makeSystem();
|
||||||
Heap* h = makeHeap(s, HeapCapacity * 2);
|
Heap* h = makeHeap(s, HeapCapacity * 2);
|
||||||
Classpath* c = makeClasspath(s, h, AVIAN_JAVA_HOME, AVIAN_EMBED_PREFIX);
|
Classpath* c = makeClasspath(s, h, AVIAN_JAVA_HOME, AVIAN_EMBED_PREFIX);
|
||||||
Finder* f = makeFinder(s, h, args.classpath, 0);
|
Finder* f = makeFinder(s, h, args.classpath, 0);
|
||||||
Processor* p = makeProcessor(s, h, false);
|
Processor* p = makeProcessor(s, h, 0, false);
|
||||||
|
|
||||||
// todo: currently, the compiler cannot compile code with jumps or
|
// todo: currently, the compiler cannot compile code with jumps or
|
||||||
// calls spanning more than the maximum size of an immediate value
|
// calls spanning more than the maximum size of an immediate value
|
||||||
|
@ -1941,7 +1941,7 @@ main(int ac, char** av)
|
|||||||
local::usageAndExit(av[0]);
|
local::usageAndExit(av[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* system = makeSystem(0);
|
System* system = makeSystem();
|
||||||
|
|
||||||
class MyAllocator: public Allocator {
|
class MyAllocator: public Allocator {
|
||||||
public:
|
public:
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "avian/common.h"
|
#include "avian/common.h"
|
||||||
#include <avian/vm/heap/heap.h>
|
#include <avian/heap/heap.h>
|
||||||
#include <avian/vm/system/system.h>
|
#include <avian/system/system.h>
|
||||||
#include "avian/target.h"
|
#include "avian/target.h"
|
||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/architecture.h>
|
#include <avian/codegen/architecture.h>
|
||||||
#include <avian/vm/codegen/targets.h>
|
#include <avian/codegen/targets.h>
|
||||||
#include <avian/vm/codegen/lir.h>
|
#include <avian/codegen/lir.h>
|
||||||
|
|
||||||
#include "test-harness.h"
|
#include "test-harness.h"
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public:
|
|||||||
Architecture* arch;
|
Architecture* arch;
|
||||||
|
|
||||||
BasicEnv():
|
BasicEnv():
|
||||||
s(makeSystem(0)),
|
s(makeSystem()),
|
||||||
heap(makeHeap(s, 32 * 1024)),
|
heap(makeHeap(s, 32 * 1024)),
|
||||||
arch(makeArchitectureNative(s, true))
|
arch(makeArchitectureNative(s, true))
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <avian/vm/codegen/registers.h>
|
#include <avian/codegen/registers.h>
|
||||||
|
|
||||||
#include "test-harness.h"
|
#include "test-harness.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user