mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
update makefile to optionally build and use a boot image; various bugfixes
This commit is contained in:
parent
0ef2ee1d02
commit
0ec5ad3701
55
makefile
55
makefile
@ -59,7 +59,6 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
|||||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
|
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
|
||||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(native-build) \
|
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(native-build) \
|
||||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||||
-DBOOT_CLASSPATH=\"[classpathJar]\"
|
|
||||||
|
|
||||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||||
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
||||||
@ -187,7 +186,9 @@ vm-depends = \
|
|||||||
$(src)/util.h \
|
$(src)/util.h \
|
||||||
$(src)/zone.h \
|
$(src)/zone.h \
|
||||||
$(src)/assembler.h \
|
$(src)/assembler.h \
|
||||||
$(src)/compiler.h
|
$(src)/compiler.h \
|
||||||
|
$(src)/heapwalk.h \
|
||||||
|
$(src)/bootimage.h
|
||||||
|
|
||||||
vm-sources = \
|
vm-sources = \
|
||||||
$(src)/$(system).cpp \
|
$(src)/$(system).cpp \
|
||||||
@ -227,10 +228,21 @@ ifeq ($(heapdump),true)
|
|||||||
cflags += -DAVIAN_HEAPDUMP
|
cflags += -DAVIAN_HEAPDUMP
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bootimage-sources = $(src)/bootimage.cpp
|
bootimage-generator-sources = $(src)/bootimage.cpp
|
||||||
bootimage-objects = \
|
bootimage-generator-objects = \
|
||||||
$(call cpp-objects,$(bootimage-sources),$(src),$(native-build))
|
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(native-build))
|
||||||
bootimage = $(native-build)/bootimage
|
bootimage-generator = $(native-build)/bootimage-generator
|
||||||
|
|
||||||
|
bootimage-bin = $(native-build)/bootimage.bin
|
||||||
|
bootimage-object = $(native-build)/bootimage-bin.o
|
||||||
|
|
||||||
|
ifeq ($(bootimage),true)
|
||||||
|
vm-classpath-object = $(bootimage-object)
|
||||||
|
cflags += -DBOOT_IMAGE=\"bootimageBin\"
|
||||||
|
else
|
||||||
|
vm-classpath-object = $(classpath-object)
|
||||||
|
cflags += -DBOOT_CLASSPATH=\"[classpathJar]\"
|
||||||
|
endif
|
||||||
|
|
||||||
driver-source = $(src)/main.cpp
|
driver-source = $(src)/main.cpp
|
||||||
driver-object = $(native-build)/main.o
|
driver-object = $(native-build)/main.o
|
||||||
@ -269,7 +281,7 @@ args = $(flags) $(input)
|
|||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: $(static-library) $(executable) $(dynamic-library) \
|
build: $(static-library) $(executable) $(dynamic-library) \
|
||||||
$(executable-dynamic) $(classpath-dep) $(test-dep) $(bootimage)
|
$(executable-dynamic) $(classpath-dep) $(test-dep)
|
||||||
|
|
||||||
$(test-classes): $(classpath-dep)
|
$(test-classes): $(classpath-dep)
|
||||||
|
|
||||||
@ -356,7 +368,7 @@ $(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
|||||||
$(vm-asm-objects): $(native-build)/%-asm.o: $(src)/%.S
|
$(vm-asm-objects): $(native-build)/%-asm.o: $(src)/%.S
|
||||||
$(compile-asm-object)
|
$(compile-asm-object)
|
||||||
|
|
||||||
$(bootimage-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
$(bootimage-generator-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
$(heapwalk-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
$(heapwalk-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||||
@ -409,9 +421,24 @@ $(static-library): $(vm-objects) $(jni-objects)
|
|||||||
$(ar) cru $(@) $(^)
|
$(ar) cru $(@) $(^)
|
||||||
$(ranlib) $(@)
|
$(ranlib) $(@)
|
||||||
|
|
||||||
|
$(bootimage-bin): $(bootimage-generator)
|
||||||
|
$(<) $(classpath-build) > $(@)
|
||||||
|
|
||||||
|
$(bootimage-object): $(bootimage-bin)
|
||||||
|
@echo "creating $(@)"
|
||||||
|
ifeq ($(platform),darwin)
|
||||||
|
$(binaryToMacho) $(<) \
|
||||||
|
__binary_bootimage_bin_start __binary_bootimage_bin_end > $(@)
|
||||||
|
else
|
||||||
|
(wd=$$(pwd); \
|
||||||
|
cd $(native-build); \
|
||||||
|
$(objcopy) -I binary bootimage.bin \
|
||||||
|
-O $(object-format) -B $(object-arch) "$${wd}/$(@)")
|
||||||
|
endif
|
||||||
|
|
||||||
$(executable): \
|
$(executable): \
|
||||||
$(vm-objects) $(classpath-object) $(jni-objects) $(driver-object) \
|
$(vm-objects) $(jni-objects) $(driver-object) $(vm-heapwalk-objects) \
|
||||||
$(vm-heapwalk-objects) $(boot-object)
|
$(boot-object) $(vm-classpath-object)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
$(dlltool) -z $(@).def $(^)
|
$(dlltool) -z $(@).def $(^)
|
||||||
@ -422,9 +449,9 @@ else
|
|||||||
endif
|
endif
|
||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
$(bootimage): \
|
$(bootimage-generator): \
|
||||||
$(vm-objects) $(classpath-object) $(jni-objects) $(heapwalk-objects) \
|
$(vm-objects) $(classpath-object) $(jni-objects) $(heapwalk-objects) \
|
||||||
$(bootimage-objects)
|
$(bootimage-generator-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
$(dlltool) -z $(@).def $(^)
|
$(dlltool) -z $(@).def $(^)
|
||||||
@ -436,8 +463,8 @@ endif
|
|||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
$(dynamic-library): \
|
$(dynamic-library): \
|
||||||
$(vm-objects) $(classpath-object) $(dynamic-object) $(jni-objects) \
|
$(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \
|
||||||
$(vm-heapwalk-objects) $(boot-object)
|
$(boot-object) $(vm-classpath-object)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
$(cc) $(^) $(shared) $(lflags) -o $(@)
|
$(cc) $(^) $(shared) $(lflags) -o $(@)
|
||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
@ -211,7 +211,8 @@ class Assembler {
|
|||||||
|
|
||||||
virtual unsigned length() = 0;
|
virtual unsigned length() = 0;
|
||||||
|
|
||||||
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
|
virtual void updateCall(UnaryOperation op, bool assertAlignment,
|
||||||
|
void* returnAddress, void* newTarget) = 0;
|
||||||
|
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
30
src/boot.cpp
30
src/boot.cpp
@ -15,6 +15,34 @@
|
|||||||
// ourselves:
|
// ourselves:
|
||||||
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
||||||
|
|
||||||
|
#ifdef BOOT_IMAGE
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
# define EXPORT __declspec(dllexport)
|
||||||
|
# define SYMBOL(x) binary_bootimage_bin_##x
|
||||||
|
#else
|
||||||
|
# define EXPORT __attribute__ ((visibility("default")))
|
||||||
|
# define SYMBOL(x) _binary_bootimage_bin_##x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
extern const uint8_t SYMBOL(start)[];
|
||||||
|
extern const uint8_t SYMBOL(end)[];
|
||||||
|
|
||||||
|
EXPORT const uint8_t*
|
||||||
|
bootimageBin(unsigned* size)
|
||||||
|
{
|
||||||
|
*size = SYMBOL(end) - SYMBOL(start);
|
||||||
|
return SYMBOL(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif//BOOT_IMAGE
|
||||||
|
|
||||||
|
#ifdef BOOT_CLASSPATH
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
# define EXPORT __declspec(dllexport)
|
# define EXPORT __declspec(dllexport)
|
||||||
# define SYMBOL(x) binary_classpath_jar_##x
|
# define SYMBOL(x) binary_classpath_jar_##x
|
||||||
@ -36,3 +64,5 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif//BOOT_CLASSPATH
|
||||||
|
@ -106,22 +106,18 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
class Visitor: public HeapVisitor {
|
class Visitor: public HeapVisitor {
|
||||||
public:
|
public:
|
||||||
Visitor(Thread* t, uintptr_t* heap, uintptr_t* map, unsigned capacity):
|
Visitor(Thread* t, uintptr_t* heap, uintptr_t* map, unsigned capacity):
|
||||||
t(t), currentObject(0), currentOffset(0), heap(heap), map(map),
|
t(t), current(0), heap(heap), map(map), position(0), capacity(capacity)
|
||||||
position(0), capacity(capacity)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void visit(unsigned number) {
|
void visit(unsigned number) {
|
||||||
if (currentObject) {
|
if (current) {
|
||||||
unsigned index = currentObject - 1 + currentOffset;
|
if (number) markBit(map, current - 1);
|
||||||
markBit(map, index);
|
heap[current - 1] = number;
|
||||||
heap[index] = number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentObject = number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void root() {
|
virtual void root() {
|
||||||
currentObject = 0;
|
current = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned visitNew(object p) {
|
virtual unsigned visitNew(object p) {
|
||||||
@ -146,17 +142,16 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
visit(number);
|
visit(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void push(unsigned offset) {
|
virtual void push(object, unsigned number, unsigned offset) {
|
||||||
currentOffset = offset;
|
current = number + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void pop() {
|
virtual void pop() {
|
||||||
currentObject = 0;
|
current = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread* t;
|
Thread* t;
|
||||||
unsigned currentObject;
|
unsigned current;
|
||||||
unsigned currentOffset;
|
|
||||||
uintptr_t* heap;
|
uintptr_t* heap;
|
||||||
uintptr_t* map;
|
uintptr_t* map;
|
||||||
unsigned position;
|
unsigned position;
|
||||||
@ -176,8 +171,8 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap,
|
|||||||
HeapMap* heapTable)
|
HeapMap* heapTable)
|
||||||
{
|
{
|
||||||
for (; constants; constants = tripleThird(t, constants)) {
|
for (; constants; constants = tripleThird(t, constants)) {
|
||||||
intptr_t target = heapTable->find(tripleFirst(t, constants));
|
unsigned target = heapTable->find(tripleFirst(t, constants));
|
||||||
assert(t, target >= 0);
|
assert(t, target > 0);
|
||||||
|
|
||||||
void* dst = static_cast<ListenPromise*>
|
void* dst = static_cast<ListenPromise*>
|
||||||
(pointerValue(t, tripleSecond(t, constants)))->listener->resolve(target);
|
(pointerValue(t, tripleSecond(t, constants)))->listener->resolve(target);
|
||||||
@ -226,7 +221,7 @@ writeBootImage(Thread* t, FILE* out)
|
|||||||
|
|
||||||
image.magic = BootImage::Magic;
|
image.magic = BootImage::Magic;
|
||||||
|
|
||||||
if (true) {
|
if (false) {
|
||||||
fprintf(stderr, "heap size %d code size %d\n",
|
fprintf(stderr, "heap size %d code size %d\n",
|
||||||
image.heapSize, image.codeSize);
|
image.heapSize, image.codeSize);
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,17 @@ codeMapSize(unsigned codeSize)
|
|||||||
inline unsigned
|
inline unsigned
|
||||||
heapMapSize(unsigned heapSize)
|
heapMapSize(unsigned heapSize)
|
||||||
{
|
{
|
||||||
return ceiling(heapSize, BitsPerWord * 8) * BytesPerWord;
|
return ceiling(heapSize, BitsPerWord * BytesPerWord) * BytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
bootObject(uintptr_t* heap, unsigned offset)
|
||||||
|
{
|
||||||
|
if (offset) {
|
||||||
|
return reinterpret_cast<object>(heap + offset - 1);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -4050,6 +4050,14 @@ compile(MyThread* t, Allocator* allocator, Context* context)
|
|||||||
return finish(t, allocator, context);
|
return finish(t, allocator, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
updateCall(MyThread* t, UnaryOperation op, bool assertAlignment,
|
||||||
|
void* returnAddress, void* target)
|
||||||
|
{
|
||||||
|
Context context(t);
|
||||||
|
context.assembler->updateCall(op, assertAlignment, returnAddress, target);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
|
compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
|
||||||
object method);
|
object method);
|
||||||
@ -4081,9 +4089,9 @@ compileMethod2(MyThread* t)
|
|||||||
(t, resolveThisPointer(t, t->stack, target)), methodOffset(t, target))
|
(t, resolveThisPointer(t, t->stack, target)), methodOffset(t, target))
|
||||||
= address;
|
= address;
|
||||||
} else {
|
} else {
|
||||||
Context context(t);
|
updateCall
|
||||||
context.assembler->updateCall
|
(t, LongCall, true, reinterpret_cast<void*>(callNodeAddress(t, node)),
|
||||||
(reinterpret_cast<void*>(callNodeAddress(t, node)), address);
|
address);
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
@ -5117,37 +5125,38 @@ class MyProcessor: public Processor {
|
|||||||
image->methodTreeSentinal = w->visitRoot(methodTreeSentinal);
|
image->methodTreeSentinal = w->visitRoot(methodTreeSentinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void boot(Thread* t, BootImage* image, uintptr_t* heap,
|
virtual void boot(Thread* vmt, BootImage* image, uintptr_t* heap,
|
||||||
uint8_t* code)
|
uint8_t* code)
|
||||||
{
|
{
|
||||||
methodTree = reinterpret_cast<object>(heap + image->methodTree);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
methodTreeSentinal = reinterpret_cast<object>
|
methodTree = bootObject(heap, image->methodTree);
|
||||||
(heap + image->methodTreeSentinal);
|
methodTreeSentinal = bootObject(heap, image->methodTreeSentinal);
|
||||||
|
|
||||||
callTable = fixupCallTable
|
callTable = fixupCallTable
|
||||||
(static_cast<MyThread*>(t),
|
(t, bootObject(heap, image->callTable), image->codeBase,
|
||||||
reinterpret_cast<object>(heap + image->callTable),
|
|
||||||
image->codeBase,
|
|
||||||
reinterpret_cast<uintptr_t>(code));
|
reinterpret_cast<uintptr_t>(code));
|
||||||
|
|
||||||
defaultThunk = code + image->defaultThunk;
|
defaultThunk = code + image->defaultThunk;
|
||||||
{ void* p = voidPointer(::compileMethod);
|
|
||||||
memcpy(code + image->compileMethodCall, &p, BytesPerWord); }
|
updateCall(t, LongCall, false, code + image->compileMethodCall,
|
||||||
|
voidPointer(::compileMethod));
|
||||||
|
|
||||||
nativeThunk = code + image->nativeThunk;
|
nativeThunk = code + image->nativeThunk;
|
||||||
{ void* p = voidPointer(invokeNative);
|
|
||||||
memcpy(code + image->invokeNativeCall, &p, BytesPerWord); }
|
updateCall(t, LongCall, false, code + image->invokeNativeCall,
|
||||||
|
voidPointer(invokeNative));
|
||||||
|
|
||||||
aioobThunk = code + image->aioobThunk;
|
aioobThunk = code + image->aioobThunk;
|
||||||
{ void* p = voidPointer(throwArrayIndexOutOfBounds);
|
|
||||||
memcpy(code + image->throwArrayIndexOutOfBoundsCall, &p, BytesPerWord); }
|
updateCall(t, LongCall, false,
|
||||||
|
code + image->throwArrayIndexOutOfBoundsCall,
|
||||||
|
voidPointer(throwArrayIndexOutOfBounds));
|
||||||
|
|
||||||
thunkTable = code + image->thunkTable;
|
thunkTable = code + image->thunkTable;
|
||||||
thunkSize = image->thunkSize;
|
thunkSize = image->thunkSize;
|
||||||
|
|
||||||
#define THUNK(s) \
|
#define THUNK(s) \
|
||||||
{ void* p = voidPointer(s); \
|
updateCall(t, LongJump, false, code + image->s##Call, voidPointer(s));
|
||||||
memcpy(code + image->s##Call, &p, BytesPerWord); }
|
|
||||||
|
|
||||||
#include "thunks.cpp"
|
#include "thunks.cpp"
|
||||||
|
|
||||||
@ -5261,36 +5270,42 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
|
|||||||
p->defaultThunk = finish
|
p->defaultThunk = finish
|
||||||
(t, allocator, defaultContext.context.assembler, "default");
|
(t, allocator, defaultContext.context.assembler, "default");
|
||||||
|
|
||||||
{ void* call = defaultContext.promise.listener->resolve
|
{ uint8_t* call = static_cast<uint8_t*>
|
||||||
(reinterpret_cast<intptr_t>(voidPointer(compileMethod)));
|
(defaultContext.promise.listener->resolve
|
||||||
|
(reinterpret_cast<intptr_t>(voidPointer(compileMethod))))
|
||||||
|
+ BytesPerWord;
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
image->defaultThunk = p->defaultThunk - imageBase;
|
image->defaultThunk = p->defaultThunk - imageBase;
|
||||||
image->compileMethodCall = static_cast<uint8_t*>(call) - imageBase;
|
image->compileMethodCall = call - imageBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->nativeThunk = finish
|
p->nativeThunk = finish
|
||||||
(t, allocator, nativeContext.context.assembler, "native");
|
(t, allocator, nativeContext.context.assembler, "native");
|
||||||
|
|
||||||
{ void* call = nativeContext.promise.listener->resolve
|
{ uint8_t* call = static_cast<uint8_t*>
|
||||||
(reinterpret_cast<intptr_t>(voidPointer(invokeNative)));
|
(nativeContext.promise.listener->resolve
|
||||||
|
(reinterpret_cast<intptr_t>(voidPointer(invokeNative))))
|
||||||
|
+ BytesPerWord;
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
image->nativeThunk = p->nativeThunk - imageBase;
|
image->nativeThunk = p->nativeThunk - imageBase;
|
||||||
image->invokeNativeCall = static_cast<uint8_t*>(call) - imageBase;
|
image->invokeNativeCall = call - imageBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->aioobThunk = finish
|
p->aioobThunk = finish
|
||||||
(t, allocator, aioobContext.context.assembler, "aioob");
|
(t, allocator, aioobContext.context.assembler, "aioob");
|
||||||
|
|
||||||
{ void* call = aioobContext.promise.listener->resolve
|
{ uint8_t* call = static_cast<uint8_t*>
|
||||||
(reinterpret_cast<intptr_t>(voidPointer(throwArrayIndexOutOfBounds)));
|
(aioobContext.promise.listener->resolve
|
||||||
|
(reinterpret_cast<intptr_t>(voidPointer(throwArrayIndexOutOfBounds))))
|
||||||
|
+ BytesPerWord;
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
image->aioobThunk = p->aioobThunk - imageBase;
|
image->aioobThunk = p->aioobThunk - imageBase;
|
||||||
image->throwArrayIndexOutOfBoundsCall
|
image->throwArrayIndexOutOfBoundsCall = call - imageBase;
|
||||||
= static_cast<uint8_t*>(call) - imageBase;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5309,10 +5324,11 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
|
|||||||
#define THUNK(s) \
|
#define THUNK(s) \
|
||||||
tableContext.context.assembler->writeTo(start); \
|
tableContext.context.assembler->writeTo(start); \
|
||||||
start += p->thunkSize; \
|
start += p->thunkSize; \
|
||||||
{ void* call = tableContext.promise.listener->resolve \
|
{ uint8_t* call = static_cast<uint8_t*> \
|
||||||
(reinterpret_cast<intptr_t>(voidPointer(s))); \
|
(tableContext.promise.listener->resolve \
|
||||||
|
(reinterpret_cast<intptr_t>(voidPointer(s)))) + BytesPerWord; \
|
||||||
if (image) { \
|
if (image) { \
|
||||||
image->s##Call = static_cast<uint8_t*>(call) - imageBase; \
|
image->s##Call = call - imageBase; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ walk(Context* c, HeapVisitor* v, object p)
|
|||||||
goto pop;
|
goto pop;
|
||||||
|
|
||||||
children: {
|
children: {
|
||||||
v->push(nextChildOffset);
|
v->push(p, find(c, p)->number, nextChildOffset);
|
||||||
push(c, p, nextChildOffset);
|
push(c, p, nextChildOffset);
|
||||||
p = get(p, nextChildOffset);
|
p = get(p, nextChildOffset);
|
||||||
goto visit;
|
goto visit;
|
||||||
|
@ -28,7 +28,8 @@ class HeapVisitor {
|
|||||||
virtual void root() = 0;
|
virtual void root() = 0;
|
||||||
virtual unsigned visitNew(object value) = 0;
|
virtual unsigned visitNew(object value) = 0;
|
||||||
virtual void visitOld(object value, unsigned number) = 0;
|
virtual void visitOld(object value, unsigned number) = 0;
|
||||||
virtual void push(unsigned offset) = 0;
|
virtual void push(object parent, unsigned parentNumber,
|
||||||
|
unsigned childOffset) = 0;
|
||||||
virtual void pop() = 0;
|
virtual void pop() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1517,11 +1517,8 @@ boot(Thread* t, BootImage* image)
|
|||||||
if (w) {
|
if (w) {
|
||||||
for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
|
for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
|
||||||
if (w & (static_cast<uintptr_t>(1) << bit)) {
|
if (w & (static_cast<uintptr_t>(1) << bit)) {
|
||||||
unsigned index = ::indexOf(word, bit);
|
uintptr_t* p = heap + indexOf(word, bit);
|
||||||
uintptr_t* p = heap + index;
|
*p = reinterpret_cast<uintptr_t>(heap + (*p - 1));
|
||||||
if (*p) {
|
|
||||||
*p = reinterpret_cast<uintptr_t>(heap + *p - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
heapMap[word] = 0;
|
heapMap[word] = 0;
|
||||||
@ -1530,9 +1527,9 @@ boot(Thread* t, BootImage* image)
|
|||||||
|
|
||||||
t->m->heap->setImmortalHeap(heap, image->heapSize, heapMap);
|
t->m->heap->setImmortalHeap(heap, image->heapSize, heapMap);
|
||||||
|
|
||||||
t->m->loader = reinterpret_cast<object>(heap + image->loader);
|
t->m->loader = bootObject(heap, image->loader);
|
||||||
t->m->stringMap = reinterpret_cast<object>(heap + image->stringMap);
|
t->m->stringMap = bootObject(heap, image->stringMap);
|
||||||
t->m->types = reinterpret_cast<object>(heap + image->types);
|
t->m->types = bootObject(heap, image->types);
|
||||||
|
|
||||||
uintptr_t* codeMap = heap + ceiling(image->heapSize, BytesPerWord);
|
uintptr_t* codeMap = heap + ceiling(image->heapSize, BytesPerWord);
|
||||||
unsigned codeMapSizeInWords = ceiling
|
unsigned codeMapSizeInWords = ceiling
|
||||||
@ -1544,16 +1541,14 @@ boot(Thread* t, BootImage* image)
|
|||||||
if (w) {
|
if (w) {
|
||||||
for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
|
for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
|
||||||
if (w & (static_cast<uintptr_t>(1) << bit)) {
|
if (w & (static_cast<uintptr_t>(1) << bit)) {
|
||||||
unsigned index = ::indexOf(word, bit);
|
unsigned index = indexOf(word, bit);
|
||||||
uintptr_t v; memcpy(&v, code + index, BytesPerWord);
|
uintptr_t v; memcpy(&v, code + index, BytesPerWord);
|
||||||
if (v) {
|
|
||||||
v = reinterpret_cast<uintptr_t>(heap + v - 1);
|
v = reinterpret_cast<uintptr_t>(heap + v - 1);
|
||||||
memcpy(code + index, &v, BytesPerWord);
|
memcpy(code + index, &v, BytesPerWord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
t->m->processor->boot(t, image, heap, code);
|
t->m->processor->boot(t, image, heap, code);
|
||||||
|
|
||||||
@ -1580,6 +1575,8 @@ boot(Thread* t)
|
|||||||
{
|
{
|
||||||
Machine* m = t->m;
|
Machine* m = t->m;
|
||||||
|
|
||||||
|
m->unsafe = true;
|
||||||
|
|
||||||
m->loader = allocate(t, sizeof(void*) * 3, true);
|
m->loader = allocate(t, sizeof(void*) * 3, true);
|
||||||
memset(m->loader, 0, sizeof(void*) * 2);
|
memset(m->loader, 0, sizeof(void*) * 2);
|
||||||
|
|
||||||
@ -1882,6 +1879,8 @@ Thread::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->unsafe = false;
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
boot(this, image);
|
boot(this, image);
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,11 +79,20 @@ main(int ac, const char** av)
|
|||||||
++ vmArgs.nOptions;
|
++ vmArgs.nOptions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOT_IMAGE
|
||||||
|
++ vmArgs.nOptions;
|
||||||
|
#endif
|
||||||
|
|
||||||
JavaVMOption options[vmArgs.nOptions];
|
JavaVMOption options[vmArgs.nOptions];
|
||||||
vmArgs.options = options;
|
vmArgs.options = options;
|
||||||
|
|
||||||
unsigned optionIndex = 0;
|
unsigned optionIndex = 0;
|
||||||
|
|
||||||
|
#ifdef BOOT_IMAGE
|
||||||
|
options[optionIndex++].optionString
|
||||||
|
= const_cast<char*>("-Davian.bootimage=" BOOT_IMAGE);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BOOT_CLASSPATH
|
#ifdef BOOT_CLASSPATH
|
||||||
options[optionIndex++].optionString
|
options[optionIndex++].optionString
|
||||||
= const_cast<char*>("-Xbootclasspath:" BOOT_CLASSPATH);
|
= const_cast<char*>("-Xbootclasspath:" BOOT_CLASSPATH);
|
||||||
|
17
src/x86.cpp
17
src/x86.cpp
@ -135,7 +135,7 @@ class Task {
|
|||||||
Task* next;
|
Task* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void*
|
||||||
resolveOffset(System* s, uint8_t* instruction, unsigned instructionSize,
|
resolveOffset(System* s, uint8_t* instruction, unsigned instructionSize,
|
||||||
int64_t value)
|
int64_t value)
|
||||||
{
|
{
|
||||||
@ -146,6 +146,7 @@ resolveOffset(System* s, uint8_t* instruction, unsigned instructionSize,
|
|||||||
|
|
||||||
int32_t v4 = v;
|
int32_t v4 = v;
|
||||||
memcpy(instruction + instructionSize - 4, &v4, 4);
|
memcpy(instruction + instructionSize - 4, &v4, 4);
|
||||||
|
return instruction + instructionSize - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
class OffsetListener: public Promise::Listener {
|
class OffsetListener: public Promise::Listener {
|
||||||
@ -158,8 +159,7 @@ class OffsetListener: public Promise::Listener {
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void* resolve(int64_t value) {
|
virtual void* resolve(int64_t value) {
|
||||||
resolveOffset(s, instruction, instructionSize, value);
|
return resolveOffset(s, instruction, instructionSize, value);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -2270,10 +2270,15 @@ class MyAssembler: public Assembler {
|
|||||||
return c.code.length();
|
return c.code.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void updateCall(void* returnAddress, void* newTarget) {
|
virtual void updateCall(UnaryOperation op UNUSED,
|
||||||
|
bool assertAlignment UNUSED, void* returnAddress,
|
||||||
|
void* newTarget)
|
||||||
|
{
|
||||||
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
||||||
assert(&c, *instruction == 0xE8);
|
assert(&c, (op == LongCall and *instruction == 0xE8)
|
||||||
assert(&c, reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
or (op == LongJump and *instruction == 0xE9));
|
||||||
|
assert(&c, (not assertAlignment)
|
||||||
|
or reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
||||||
|
|
||||||
int32_t v = static_cast<uint8_t*>(newTarget)
|
int32_t v = static_cast<uint8_t*>(newTarget)
|
||||||
- static_cast<uint8_t*>(returnAddress);
|
- static_cast<uint8_t*>(returnAddress);
|
||||||
|
Loading…
Reference in New Issue
Block a user