mirror of
https://github.com/corda/corda.git
synced 2025-01-17 10:20:02 +00:00
more progress towards cross-architecture bootimage builds
This commit fixes a lot of bugs. All tests are now pass for Linux x86_64 to Linux i386 cross builds.
This commit is contained in:
parent
5d55d61c17
commit
e505cbe99d
23
makefile
23
makefile
@ -165,12 +165,13 @@ rdynamic = -rdynamic
|
|||||||
warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
||||||
-Wno-non-virtual-dtor
|
-Wno-non-virtual-dtor
|
||||||
|
|
||||||
|
target-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
|
|
||||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
||||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
|
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
|
||||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
||||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
|
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
|
||||||
-DTARGET_BYTES_PER_WORD=$(pointer-size)
|
|
||||||
|
|
||||||
ifneq (,$(filter i386 x86_64,$(arch)))
|
ifneq (,$(filter i386 x86_64,$(arch)))
|
||||||
ifeq ($(use-frame-pointer),true)
|
ifeq ($(use-frame-pointer),true)
|
||||||
@ -209,9 +210,11 @@ shared = -shared
|
|||||||
|
|
||||||
openjdk-extra-cflags = -fvisibility=hidden
|
openjdk-extra-cflags = -fvisibility=hidden
|
||||||
|
|
||||||
|
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
|
|
||||||
ifeq ($(build-arch),powerpc)
|
ifeq ($(build-arch),powerpc)
|
||||||
ifneq ($(arch),$(build-arch))
|
ifneq ($(arch),$(build-arch))
|
||||||
cflags += -DTARGET_OPPOSITE_ENDIAN
|
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -223,7 +226,7 @@ ifeq ($(arch),powerpc)
|
|||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
|
|
||||||
ifneq ($(arch),$(build-arch))
|
ifneq ($(arch),$(build-arch))
|
||||||
cflags += -DTARGET_OPPOSITE_ENDIAN
|
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(platform),darwin)
|
ifneq ($(platform),darwin)
|
||||||
@ -264,7 +267,7 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
ifeq ($(platform),linux)
|
ifeq ($(platform),linux)
|
||||||
cflags += -DTARGET_PLATFORM_LINUX
|
bootimage-cflags += -DTARGET_PLATFORM_LINUX
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(build-platform),darwin)
|
ifeq ($(build-platform),darwin)
|
||||||
@ -274,7 +277,7 @@ ifeq ($(build-platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),darwin)
|
ifeq ($(platform),darwin)
|
||||||
cflags += -DTARGET_PLATFORM_DARWIN
|
bootimage-cflags += -DTARGET_PLATFORM_DARWIN
|
||||||
|
|
||||||
ifeq (${OSX_SDK_SYSROOT},)
|
ifeq (${OSX_SDK_SYSROOT},)
|
||||||
OSX_SDK_SYSROOT = 10.4u
|
OSX_SDK_SYSROOT = 10.4u
|
||||||
@ -350,7 +353,7 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
cflags += -DTARGET_PLATFORM_WINDOWS
|
bootimage-cflags += -DTARGET_PLATFORM_WINDOWS
|
||||||
|
|
||||||
inc = "$(root)/win32/include"
|
inc = "$(root)/win32/include"
|
||||||
lib = "$(root)/win32/lib"
|
lib = "$(root)/win32/lib"
|
||||||
@ -520,10 +523,12 @@ vm-sources = \
|
|||||||
|
|
||||||
vm-asm-sources = $(src)/$(asm).S
|
vm-asm-sources = $(src)/$(asm).S
|
||||||
|
|
||||||
|
target-asm = $(asm)
|
||||||
|
|
||||||
ifeq ($(process),compile)
|
ifeq ($(process),compile)
|
||||||
vm-sources += \
|
vm-sources += \
|
||||||
$(src)/compiler.cpp \
|
$(src)/compiler.cpp \
|
||||||
$(src)/$(asm).cpp
|
$(src)/$(target-asm).cpp
|
||||||
|
|
||||||
vm-asm-sources += $(src)/compile-$(asm).S
|
vm-asm-sources += $(src)/compile-$(asm).S
|
||||||
endif
|
endif
|
||||||
@ -902,6 +907,8 @@ $(bootimage-generator):
|
|||||||
openjdk-src=$(openjdk-src) \
|
openjdk-src=$(openjdk-src) \
|
||||||
bootimage-generator= \
|
bootimage-generator= \
|
||||||
build-bootimage-generator=$(bootimage-generator) \
|
build-bootimage-generator=$(bootimage-generator) \
|
||||||
|
target-cflags="$(bootimage-cflags)" \
|
||||||
|
target-asm=$(asm) \
|
||||||
$(bootimage-generator)
|
$(bootimage-generator)
|
||||||
|
|
||||||
$(build-bootimage-generator): \
|
$(build-bootimage-generator): \
|
||||||
|
30
src/bootimage-template.cpp
Normal file
30
src/bootimage-template.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const unsigned NAME(BootMask) = (~static_cast<unsigned>(0))
|
||||||
|
/ NAME(BytesPerWord);
|
||||||
|
|
||||||
|
const unsigned NAME(BootShift) = 32 - log(NAME(BytesPerWord));
|
||||||
|
|
||||||
|
const unsigned NAME(BootFlatConstant) = 1 << NAME(BootShift);
|
||||||
|
const unsigned NAME(BootHeapOffset) = 1 << (NAME(BootShift) + 1);
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
LABEL(codeMapSize)(unsigned codeSize)
|
||||||
|
{
|
||||||
|
return ceiling(codeSize, TargetBitsPerWord) * TargetBytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
LABEL(heapMapSize)(unsigned heapSize)
|
||||||
|
{
|
||||||
|
return ceiling(heapSize, TargetBitsPerWord * TargetBytesPerWord)
|
||||||
|
* TargetBytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
LABEL(bootObject)(LABEL(uintptr_t)* heap, unsigned offset)
|
||||||
|
{
|
||||||
|
if (offset) {
|
||||||
|
return reinterpret_cast<object>(heap + offset - 1);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,6 @@
|
|||||||
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 "bootimage.h"
|
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "heapwalk.h"
|
#include "heapwalk.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -40,6 +39,7 @@ const bool DebugNativeTarget = false;
|
|||||||
enum Type {
|
enum Type {
|
||||||
Type_none,
|
Type_none,
|
||||||
Type_object,
|
Type_object,
|
||||||
|
Type_object_nogc,
|
||||||
Type_int8_t,
|
Type_int8_t,
|
||||||
Type_uint8_t,
|
Type_uint8_t,
|
||||||
Type_int16_t,
|
Type_int16_t,
|
||||||
@ -60,13 +60,19 @@ enum Type {
|
|||||||
|
|
||||||
class Field {
|
class Field {
|
||||||
public:
|
public:
|
||||||
Field(Type type, unsigned offset, unsigned targetOffset):
|
Field() { }
|
||||||
type(type), offset(offset), targetOffset(targetOffset)
|
|
||||||
|
Field(Type type, unsigned buildOffset, unsigned buildSize,
|
||||||
|
unsigned targetOffset, unsigned targetSize):
|
||||||
|
type(type), buildOffset(buildOffset), buildSize(buildSize),
|
||||||
|
targetOffset(targetOffset), targetSize(targetSize)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
unsigned offset;
|
unsigned buildOffset;
|
||||||
|
unsigned buildSize;
|
||||||
unsigned targetOffset;
|
unsigned targetOffset;
|
||||||
|
unsigned targetSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeMap {
|
class TypeMap {
|
||||||
@ -155,6 +161,108 @@ endsWith(const char* suffix, const char* s, unsigned length)
|
|||||||
and memcmp(suffix, s + (length - suffixLength), suffixLength) == 0;
|
and memcmp(suffix, s + (length - suffixLength), suffixLength) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
getNonStaticFields(Thread* t, object typeMaps, object c, object fields,
|
||||||
|
unsigned* count, object* array)
|
||||||
|
{
|
||||||
|
PROTECT(t, typeMaps);
|
||||||
|
PROTECT(t, c);
|
||||||
|
PROTECT(t, fields);
|
||||||
|
|
||||||
|
*array = hashMapFind(t, typeMaps, c, objectHash, objectEqual);
|
||||||
|
|
||||||
|
if (*array) {
|
||||||
|
*count += reinterpret_cast<TypeMap*>(&byteArrayBody(t, *array, 0))
|
||||||
|
->fixedFieldCount;
|
||||||
|
} else {
|
||||||
|
if (classSuper(t, c)) {
|
||||||
|
fields = getNonStaticFields
|
||||||
|
(t, typeMaps, classSuper(t, c), fields, count, array);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classFieldTable(t, c)) {
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, classFieldTable(t, c)); ++i) {
|
||||||
|
object field = arrayBody(t, classFieldTable(t, c), i);
|
||||||
|
|
||||||
|
if ((fieldFlags(t, field) & ACC_STATIC) == 0) {
|
||||||
|
++ (*count);
|
||||||
|
fields = vectorAppend(t, fields, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vectorAppend(t, fields, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
allFields(Thread* t, object typeMaps, object c, unsigned* count, object* array)
|
||||||
|
{
|
||||||
|
PROTECT(t, typeMaps);
|
||||||
|
PROTECT(t, c);
|
||||||
|
|
||||||
|
object fields = makeVector(t, 0, 0);
|
||||||
|
PROTECT(t, fields);
|
||||||
|
|
||||||
|
*array = hashMapFind(t, typeMaps, c, objectHash, objectEqual);
|
||||||
|
|
||||||
|
bool includeMembers;
|
||||||
|
if (*array) {
|
||||||
|
includeMembers = false;
|
||||||
|
*count += reinterpret_cast<TypeMap*>(&byteArrayBody(t, *array, 0))
|
||||||
|
->fixedFieldCount;
|
||||||
|
} else if (classSuper(t, c)) {
|
||||||
|
includeMembers = true;
|
||||||
|
fields = getNonStaticFields
|
||||||
|
(t, typeMaps, classSuper(t, c), fields, count, array);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classFieldTable(t, c)) {
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, classFieldTable(t, c)); ++i) {
|
||||||
|
object field = arrayBody(t, classFieldTable(t, c), i);
|
||||||
|
|
||||||
|
if (includeMembers or (fieldFlags(t, field) & ACC_STATIC)) {
|
||||||
|
++ (*count);
|
||||||
|
fields = vectorAppend(t, fields, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeMap*
|
||||||
|
classTypeMap(Thread* t, object typeMaps, object p)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<TypeMap*>
|
||||||
|
(&byteArrayBody
|
||||||
|
(t, hashMapFind(t, typeMaps, p, objectHash, objectEqual), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeMap*
|
||||||
|
typeMap(Thread* t, object typeMaps, object p)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<TypeMap*>
|
||||||
|
(&byteArrayBody
|
||||||
|
(t, objectClass(t, p) == type(t, Machine::SingletonType)
|
||||||
|
? hashMapFind(t, typeMaps, p, objectHash, objectEqual)
|
||||||
|
: hashMapFind(t, typeMaps, objectClass(t, p), objectHash, objectEqual),
|
||||||
|
0));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
targetFieldOffset(Thread* t, object typeMaps, object field)
|
||||||
|
{
|
||||||
|
// if (strcmp(reinterpret_cast<const char*>
|
||||||
|
// (&byteArrayBody(t, className(t, fieldClass(t, field)), 0)),
|
||||||
|
// "java/lang/Throwable") == 0) trap();
|
||||||
|
|
||||||
|
return ((fieldFlags(t, field) & ACC_STATIC)
|
||||||
|
? typeMap(t, typeMaps, classStaticTable(t, fieldClass(t, field)))
|
||||||
|
: classTypeMap(t, typeMaps, fieldClass(t, field)))
|
||||||
|
->targetFixedOffsets()[fieldOffset(t, field)];
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||||
uintptr_t* codeMap, const char* className,
|
uintptr_t* codeMap, const char* className,
|
||||||
@ -168,8 +276,22 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
object calls = 0;
|
object calls = 0;
|
||||||
PROTECT(t, calls);
|
PROTECT(t, calls);
|
||||||
|
|
||||||
|
object methods = 0;
|
||||||
|
PROTECT(t, methods);
|
||||||
|
|
||||||
DelayedPromise* addresses = 0;
|
DelayedPromise* addresses = 0;
|
||||||
|
|
||||||
|
class MyOffsetResolver: public OffsetResolver {
|
||||||
|
public:
|
||||||
|
MyOffsetResolver(object* typeMaps): typeMaps(typeMaps) { }
|
||||||
|
|
||||||
|
virtual unsigned fieldOffset(Thread* t, object field) {
|
||||||
|
return targetFieldOffset(t, *typeMaps, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
object* typeMaps;
|
||||||
|
} resolver(&typeMaps);
|
||||||
|
|
||||||
Finder* finder = static_cast<Finder*>
|
Finder* finder = static_cast<Finder*>
|
||||||
(systemClassLoaderFinder(t, root(t, Machine::BootLoader)));
|
(systemClassLoaderFinder(t, root(t, Machine::BootLoader)));
|
||||||
|
|
||||||
@ -272,7 +394,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
= i * TargetBytesPerWord;
|
= i * TargetBytesPerWord;
|
||||||
|
|
||||||
new (map->fixedFields() + i) Field
|
new (map->fixedFields() + i) Field
|
||||||
(types[i], i * BytesPerWord, i * TargetBytesPerWord);
|
(types[i], i * BytesPerWord, BytesPerWord,
|
||||||
|
i * TargetBytesPerWord, TargetBytesPerWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
hashMapInsert
|
hashMapInsert
|
||||||
@ -282,41 +405,71 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classFieldTable(t, c)) {
|
// if (strcmp(name, "java/lang/System$Property.class") == 0) trap();
|
||||||
unsigned count = arrayLength(t, classFieldTable(t, c));
|
|
||||||
|
|
||||||
Type memberTypes[count + 1];
|
{ object array = 0;
|
||||||
memberTypes[0] = Type_object;
|
PROTECT(t, array);
|
||||||
unsigned buildMemberOffsets[count + 1];
|
|
||||||
buildMemberOffsets[0] = 0;
|
unsigned count = 0;
|
||||||
unsigned targetMemberOffsets[count + 1];
|
object fields = allFields(t, typeMaps, c, &count, &array);
|
||||||
targetMemberOffsets[0] = 0;
|
PROTECT(t, fields);
|
||||||
unsigned memberIndex = 1;
|
|
||||||
unsigned buildMemberOffset = BytesPerWord;
|
Field memberFields[count + 1];
|
||||||
unsigned targetMemberOffset = TargetBytesPerWord;
|
|
||||||
|
unsigned memberIndex;
|
||||||
|
unsigned buildMemberOffset;
|
||||||
|
unsigned targetMemberOffset;
|
||||||
|
|
||||||
|
if (array) {
|
||||||
|
memberIndex = 0;
|
||||||
|
buildMemberOffset = 0;
|
||||||
|
targetMemberOffset = 0;
|
||||||
|
|
||||||
|
TypeMap* map = reinterpret_cast<TypeMap*>
|
||||||
|
(&byteArrayBody(t, array, 0));
|
||||||
|
|
||||||
|
for (unsigned j = 0; j < map->fixedFieldCount; ++j) {
|
||||||
|
Field* f = map->fixedFields() + j;
|
||||||
|
|
||||||
|
memberFields[memberIndex] = *f;
|
||||||
|
|
||||||
|
targetMemberOffset += f->targetSize;
|
||||||
|
|
||||||
|
++ memberIndex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new (memberFields) Field
|
||||||
|
(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord);
|
||||||
|
|
||||||
|
memberIndex = 1;
|
||||||
|
buildMemberOffset = BytesPerWord;
|
||||||
|
targetMemberOffset = TargetBytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
Field staticFields[count + 2];
|
||||||
|
|
||||||
|
new (staticFields) Field
|
||||||
|
(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord);
|
||||||
|
|
||||||
|
new (staticFields + 1) Field
|
||||||
|
(Type_intptr_t, BytesPerWord, BytesPerWord, TargetBytesPerWord,
|
||||||
|
TargetBytesPerWord);
|
||||||
|
|
||||||
Type staticTypes[count + 2];
|
|
||||||
staticTypes[0] = Type_object;
|
|
||||||
staticTypes[1] = Type_intptr_t;
|
|
||||||
unsigned buildStaticOffsets[count + 2];
|
|
||||||
buildStaticOffsets[0] = 0;
|
|
||||||
buildStaticOffsets[1] = BytesPerWord;
|
|
||||||
unsigned targetStaticOffsets[count + 2];
|
|
||||||
targetStaticOffsets[0] = 0;
|
|
||||||
targetStaticOffsets[1] = TargetBytesPerWord;
|
|
||||||
unsigned staticIndex = 2;
|
unsigned staticIndex = 2;
|
||||||
unsigned buildStaticOffset = BytesPerWord * 2;
|
unsigned buildStaticOffset = BytesPerWord * 2;
|
||||||
unsigned targetStaticOffset = TargetBytesPerWord * 2;
|
unsigned targetStaticOffset = TargetBytesPerWord * 2;
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < vectorSize(t, fields); ++i) {
|
||||||
object field = arrayBody(t, classFieldTable(t, c), i);
|
object field = vectorBody(t, fields, i);
|
||||||
unsigned size = fieldSize(t, fieldCode(t, field));
|
if (field) {
|
||||||
|
unsigned buildSize = fieldSize(t, fieldCode(t, field));
|
||||||
|
unsigned targetSize = buildSize;
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
switch (fieldCode(t, field)) {
|
switch (fieldCode(t, field)) {
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
type = Type_object;
|
type = Type_object;
|
||||||
size = TargetBytesPerWord;
|
targetSize = TargetBytesPerWord;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ByteField:
|
case ByteField:
|
||||||
@ -343,39 +496,43 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_STATIC) {
|
if (fieldFlags(t, field) & ACC_STATIC) {
|
||||||
staticTypes[staticIndex] = type;
|
while (targetStaticOffset % targetSize) {
|
||||||
|
|
||||||
while (targetStaticOffset % size) {
|
|
||||||
++ targetStaticOffset;
|
++ targetStaticOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetStaticOffsets[staticIndex] = targetStaticOffset;
|
|
||||||
|
|
||||||
targetStaticOffset += size;
|
|
||||||
|
|
||||||
buildStaticOffset = fieldOffset(t, field);
|
buildStaticOffset = fieldOffset(t, field);
|
||||||
buildStaticOffsets[staticIndex] = buildStaticOffset;
|
|
||||||
|
new (staticFields + staticIndex) Field
|
||||||
|
(type, buildStaticOffset, buildSize, targetStaticOffset,
|
||||||
|
targetSize);
|
||||||
|
|
||||||
|
targetStaticOffset += targetSize;
|
||||||
|
|
||||||
++ staticIndex;
|
++ staticIndex;
|
||||||
} else {
|
} else {
|
||||||
memberTypes[memberIndex] = type;
|
while (targetMemberOffset % targetSize) {
|
||||||
|
|
||||||
while (targetMemberOffset % size) {
|
|
||||||
++ targetMemberOffset;
|
++ targetMemberOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetMemberOffsets[memberIndex] = targetMemberOffset;
|
|
||||||
|
|
||||||
targetMemberOffset += size;
|
|
||||||
|
|
||||||
buildMemberOffset = fieldOffset(t, field);
|
buildMemberOffset = fieldOffset(t, field);
|
||||||
buildMemberOffsets[memberIndex] = buildMemberOffset;
|
|
||||||
|
new (memberFields + memberIndex) Field
|
||||||
|
(type, buildMemberOffset, buildSize, targetMemberOffset,
|
||||||
|
targetSize);
|
||||||
|
|
||||||
|
targetMemberOffset += targetSize;
|
||||||
|
|
||||||
++ memberIndex;
|
++ memberIndex;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
targetMemberOffset = pad(targetMemberOffset, TargetBytesPerWord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ object array = makeByteArray
|
// if (strcmp(name, "avian/VMClass.class") == 0) trap();
|
||||||
|
|
||||||
|
if (hashMapFind(t, typeMaps, c, objectHash, objectEqual) == 0) {
|
||||||
|
object array = makeByteArray
|
||||||
(t, TypeMap::sizeInBytes
|
(t, TypeMap::sizeInBytes
|
||||||
(ceiling(classFixedSize(t, c), BytesPerWord), memberIndex));
|
(ceiling(classFixedSize(t, c), BytesPerWord), memberIndex));
|
||||||
|
|
||||||
@ -384,14 +541,14 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
ceiling(targetMemberOffset, TargetBytesPerWord), memberIndex);
|
ceiling(targetMemberOffset, TargetBytesPerWord), memberIndex);
|
||||||
|
|
||||||
for (unsigned i = 0; i < memberIndex; ++i) {
|
for (unsigned i = 0; i < memberIndex; ++i) {
|
||||||
expect(t, buildMemberOffsets[i]
|
Field* f = memberFields + i;
|
||||||
|
|
||||||
|
expect(t, f->buildOffset
|
||||||
< map->buildFixedSizeInWords * BytesPerWord);
|
< map->buildFixedSizeInWords * BytesPerWord);
|
||||||
|
|
||||||
map->targetFixedOffsets()[buildMemberOffsets[i]]
|
map->targetFixedOffsets()[f->buildOffset] = f->targetOffset;
|
||||||
= targetMemberOffsets[i];
|
|
||||||
|
|
||||||
new (map->fixedFields() + i) Field
|
map->fixedFields()[i] = *f;
|
||||||
(memberTypes[i], buildMemberOffsets[i], targetMemberOffsets[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hashMapInsert(t, typeMaps, c, array, objectHash);
|
hashMapInsert(t, typeMaps, c, array, objectHash);
|
||||||
@ -408,20 +565,36 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
TypeMap::SingletonKind);
|
TypeMap::SingletonKind);
|
||||||
|
|
||||||
for (unsigned i = 0; i < staticIndex; ++i) {
|
for (unsigned i = 0; i < staticIndex; ++i) {
|
||||||
expect(t, buildStaticOffsets[i]
|
Field* f = staticFields + i;
|
||||||
|
|
||||||
|
expect(t, f->buildOffset
|
||||||
< map->buildFixedSizeInWords * BytesPerWord);
|
< map->buildFixedSizeInWords * BytesPerWord);
|
||||||
|
|
||||||
map->targetFixedOffsets()[buildStaticOffsets[i]]
|
map->targetFixedOffsets()[f->buildOffset] = f->targetOffset;
|
||||||
= targetStaticOffsets[i];
|
|
||||||
|
|
||||||
new (map->fixedFields() + i) Field
|
map->fixedFields()[i] = *f;
|
||||||
(staticTypes[i], buildStaticOffsets[i], targetStaticOffsets[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hashMapInsert
|
hashMapInsert
|
||||||
(t, typeMaps, classStaticTable(t, c), array, objectHash);
|
(t, typeMaps, classStaticTable(t, c), array, objectHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Finder::Iterator it(finder); it.hasMore();) {
|
||||||
|
unsigned nameSize = 0;
|
||||||
|
const char* name = it.next(&nameSize);
|
||||||
|
|
||||||
|
if (endsWith(".class", name, nameSize)
|
||||||
|
and (className == 0 or strncmp(name, className, nameSize - 6) == 0))
|
||||||
|
{
|
||||||
|
// fprintf(stderr, "%.*s\n", nameSize - 6, name);
|
||||||
|
object c = resolveSystemClass
|
||||||
|
(t, root(t, Machine::BootLoader),
|
||||||
|
makeByteArray(t, "%.*s", nameSize - 6, name), true);
|
||||||
|
|
||||||
|
PROTECT(t, c);
|
||||||
|
|
||||||
if (classMethodTable(t, c)) {
|
if (classMethodTable(t, c)) {
|
||||||
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
||||||
@ -444,7 +617,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
|
|
||||||
t->m->processor->compileMethod
|
t->m->processor->compileMethod
|
||||||
(t, zone, &constants, &calls, &addresses, method);
|
(t, zone, &constants, &calls, &addresses, method, &resolver);
|
||||||
|
|
||||||
|
if (methodCode(t, method)) {
|
||||||
|
methods = makePair(t, method, methods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object addendum = methodAddendum(t, method);
|
object addendum = methodAddendum(t, method);
|
||||||
@ -499,7 +676,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
(reinterpret_cast<int64_t>(code), &location);
|
(reinterpret_cast<int64_t>(code), &location);
|
||||||
target_uintptr_t offset = value - code;
|
target_uintptr_t offset = value - code;
|
||||||
if (flat) {
|
if (flat) {
|
||||||
offset |= BootFlatConstant;
|
offset |= TargetBootFlatConstant;
|
||||||
}
|
}
|
||||||
memcpy(location, &offset, TargetBytesPerWord);
|
memcpy(location, &offset, TargetBytesPerWord);
|
||||||
|
|
||||||
@ -510,6 +687,13 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
- reinterpret_cast<intptr_t>(code));
|
- reinterpret_cast<intptr_t>(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (; methods; methods = pairSecond(t, methods)) {
|
||||||
|
codeCompiled(t, methodCode(t, pairFirst(t, methods)))
|
||||||
|
-= reinterpret_cast<uintptr_t>(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
t->m->processor->normalizeVirtualThunks(t);
|
||||||
|
|
||||||
return constants;
|
return constants;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,17 +725,6 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeMap*
|
|
||||||
typeMap(Thread* t, object typeMaps, object p)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<TypeMap*>
|
|
||||||
(&byteArrayBody
|
|
||||||
(t, objectClass(t, p) == type(t, Machine::SingletonType)
|
|
||||||
? hashMapFind(t, typeMaps, p, objectHash, objectEqual)
|
|
||||||
: hashMapFind(t, typeMaps, objectClass(t, p), objectHash, objectEqual),
|
|
||||||
0));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
targetOffset(Thread* t, object typeMaps, object p, unsigned offset)
|
targetOffset(Thread* t, object typeMaps, object p, unsigned offset)
|
||||||
{
|
{
|
||||||
@ -602,6 +775,36 @@ targetSize(Thread* t, object typeMaps, object p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
objectMaskCount(TypeMap* map)
|
||||||
|
{
|
||||||
|
unsigned count = map->targetFixedSizeInWords;
|
||||||
|
|
||||||
|
if (map->targetArrayElementSizeInBytes) {
|
||||||
|
++ count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
targetSize(Thread* t, object typeMaps, object referer, unsigned refererOffset,
|
||||||
|
object p)
|
||||||
|
{
|
||||||
|
if (referer
|
||||||
|
and objectClass(t, referer) == type(t, Machine::ClassType)
|
||||||
|
and (refererOffset * BytesPerWord) == ClassObjectMask)
|
||||||
|
{
|
||||||
|
return (TargetBytesPerWord * 2)
|
||||||
|
+ pad
|
||||||
|
(ceiling
|
||||||
|
(objectMaskCount
|
||||||
|
(classTypeMap(t, typeMaps, referer)), 32) * 4, TargetBytesPerWord);
|
||||||
|
} else {
|
||||||
|
return targetSize(t, typeMaps, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copy(Thread* t, uint8_t* src, uint8_t* dst, Type type)
|
copy(Thread* t, uint8_t* src, uint8_t* dst, Type type)
|
||||||
{
|
{
|
||||||
@ -674,6 +877,7 @@ nonObjectsEqual(uint8_t* src, uint8_t* dst, Type type)
|
|||||||
return memcmp(dst, src, BytesPerWord) == 0;
|
return memcmp(dst, src, BytesPerWord) == 0;
|
||||||
|
|
||||||
case Type_object:
|
case Type_object:
|
||||||
|
case Type_object_nogc:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default: abort();
|
default: abort();
|
||||||
@ -686,7 +890,7 @@ nonObjectsEqual(TypeMap* map, uint8_t* src, uint8_t* dst)
|
|||||||
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
||||||
Field* field = map->fixedFields() + i;
|
Field* field = map->fixedFields() + i;
|
||||||
if (not nonObjectsEqual
|
if (not nonObjectsEqual
|
||||||
(src + field->offset, dst + field->targetOffset, field->type))
|
(src + field->buildOffset, dst + field->targetOffset, field->type))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -720,7 +924,7 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst)
|
|||||||
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
||||||
Field* field = map->fixedFields() + i;
|
Field* field = map->fixedFields() + i;
|
||||||
if (field->type > Type_array) abort(t);
|
if (field->type > Type_array) abort(t);
|
||||||
copy(t, src + field->offset, dst + field->targetOffset, field->type);
|
copy(t, src + field->buildOffset, dst + field->targetOffset, field->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map->targetArrayElementSizeInBytes) {
|
if (map->targetArrayElementSizeInBytes) {
|
||||||
@ -732,16 +936,59 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst)
|
|||||||
dst + (map->targetFixedSizeInWords * TargetBytesPerWord)
|
dst + (map->targetFixedSizeInWords * TargetBytesPerWord)
|
||||||
+ (i * map->targetArrayElementSizeInBytes), map->arrayElementType);
|
+ (i * map->targetArrayElementSizeInBytes), map->arrayElementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (objectClass(t, p) == type(t, Machine::ClassType)) {
|
||||||
|
uint16_t fixedSize;
|
||||||
|
uint8_t arrayElementSize;
|
||||||
|
object array = hashMapFind(t, typeMaps, p, objectHash, objectEqual);
|
||||||
|
|
||||||
|
if (array) {
|
||||||
|
TypeMap* classMap = reinterpret_cast<TypeMap*>
|
||||||
|
(&byteArrayBody(t, array, 0));
|
||||||
|
|
||||||
|
fixedSize = TARGET_V2
|
||||||
|
(classMap->targetFixedSizeInWords * TargetBytesPerWord);
|
||||||
|
|
||||||
|
arrayElementSize = classMap->targetArrayElementSizeInBytes;
|
||||||
|
} else if (classFixedSize(t, p) == BytesPerWord * 2
|
||||||
|
and classArrayElementSize(t, p) == BytesPerWord)
|
||||||
|
{
|
||||||
|
fixedSize = TARGET_V2(TargetBytesPerWord * 2);
|
||||||
|
|
||||||
|
arrayElementSize = TargetBytesPerWord;
|
||||||
|
} else {
|
||||||
|
fixedSize = 0;
|
||||||
|
arrayElementSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixedSize) {
|
||||||
|
memcpy(dst + TargetClassFixedSize, &fixedSize, 2);
|
||||||
|
|
||||||
|
memcpy(dst + TargetClassArrayElementSize, &arrayElementSize, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (strcmp("vm::lineNumberTable",
|
||||||
|
// reinterpret_cast<const char*>(&byteArrayBody(t, className(t, p), 0))) == 0) trap();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (map->kind) {
|
switch (map->kind) {
|
||||||
case TypeMap::NormalKind:
|
case TypeMap::NormalKind:
|
||||||
|
if (objectClass(t, p) == type(t, Machine::FieldType)) {
|
||||||
|
uint16_t offset = TARGET_V2(targetFieldOffset(t, typeMaps, p));
|
||||||
|
memcpy(dst + TargetFieldOffset, &offset, 2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TypeMap::SingletonKind: {
|
case TypeMap::SingletonKind: {
|
||||||
|
unsigned maskSize = singletonMaskSize
|
||||||
|
(map->targetFixedSizeInWords - 2, TargetBitsPerWord);
|
||||||
|
|
||||||
|
target_uintptr_t targetLength = TARGET_VW
|
||||||
|
(map->targetFixedSizeInWords - 2 + maskSize);
|
||||||
|
memcpy(dst + TargetBytesPerWord, &targetLength, TargetBytesPerWord);
|
||||||
|
|
||||||
uint8_t* mask = dst + (map->targetFixedSizeInWords * TargetBytesPerWord);
|
uint8_t* mask = dst + (map->targetFixedSizeInWords * TargetBytesPerWord);
|
||||||
memset(mask, 0, singletonMaskSize
|
memset(mask, 0, maskSize * TargetBytesPerWord);
|
||||||
(map->targetFixedSizeInWords - 2, TargetBitsPerWord)
|
|
||||||
* TargetBytesPerWord);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
||||||
Field* field = map->fixedFields() + i;
|
Field* field = map->fixedFields() + i;
|
||||||
@ -766,6 +1013,13 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst)
|
|||||||
unsigned poolMaskSize = vm::poolMaskSize
|
unsigned poolMaskSize = vm::poolMaskSize
|
||||||
(map->targetFixedSizeInWords - 2, TargetBitsPerWord);
|
(map->targetFixedSizeInWords - 2, TargetBitsPerWord);
|
||||||
|
|
||||||
|
unsigned objectMaskSize = singletonMaskSize
|
||||||
|
(map->targetFixedSizeInWords - 2 + poolMaskSize, TargetBitsPerWord);
|
||||||
|
|
||||||
|
target_uintptr_t targetLength = TARGET_VW
|
||||||
|
(map->targetFixedSizeInWords - 2 + poolMaskSize + objectMaskSize);
|
||||||
|
memcpy(dst + TargetBytesPerWord, &targetLength, TargetBytesPerWord);
|
||||||
|
|
||||||
uint8_t* poolMask = dst
|
uint8_t* poolMask = dst
|
||||||
+ (map->targetFixedSizeInWords * TargetBytesPerWord);
|
+ (map->targetFixedSizeInWords * TargetBytesPerWord);
|
||||||
|
|
||||||
@ -774,9 +1028,7 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst)
|
|||||||
uint8_t* objectMask = dst
|
uint8_t* objectMask = dst
|
||||||
+ ((map->targetFixedSizeInWords + poolMaskSize) * TargetBytesPerWord);
|
+ ((map->targetFixedSizeInWords + poolMaskSize) * TargetBytesPerWord);
|
||||||
|
|
||||||
memset(objectMask, 0, singletonMaskSize
|
memset(objectMask, 0, objectMaskSize * TargetBytesPerWord);
|
||||||
(map->targetFixedSizeInWords - 2 + poolMaskSize,
|
|
||||||
TargetBitsPerWord) * TargetBytesPerWord);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
||||||
Field* field = map->fixedFields() + i;
|
Field* field = map->fixedFields() + i;
|
||||||
@ -812,21 +1064,64 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst)
|
|||||||
default: abort(t);
|
default: abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
copy(Thread* t, object typeMaps, object referer, unsigned refererOffset,
|
||||||
|
object p, uint8_t* dst)
|
||||||
|
{
|
||||||
|
if (referer
|
||||||
|
and objectClass(t, referer) == type(t, Machine::ClassType)
|
||||||
|
and (refererOffset * BytesPerWord) == ClassObjectMask)
|
||||||
|
{
|
||||||
|
TypeMap* map = classTypeMap(t, typeMaps, referer);
|
||||||
|
|
||||||
|
memset(dst, 0, TargetBytesPerWord);
|
||||||
|
|
||||||
|
unsigned length = ceiling(objectMaskCount(map), 32);
|
||||||
|
|
||||||
|
target_uintptr_t targetLength = TARGET_VW(length);
|
||||||
|
|
||||||
|
memcpy(dst + TargetBytesPerWord, &targetLength, TargetBytesPerWord);
|
||||||
|
|
||||||
|
memset(dst + (TargetBytesPerWord * 2), 0, length * 4);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < map->fixedFieldCount; ++i) {
|
||||||
|
Field* field = map->fixedFields() + i;
|
||||||
|
if (field->type == Type_object) {
|
||||||
|
unsigned offset = field->targetOffset / TargetBytesPerWord;
|
||||||
|
reinterpret_cast<uint32_t*>(dst + (TargetBytesPerWord * 2))
|
||||||
|
[offset / 32] |= static_cast<uint32_t>(1) << (offset % 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map->targetArrayElementSizeInBytes
|
||||||
|
and map->arrayElementType == Type_object)
|
||||||
|
{
|
||||||
|
unsigned offset = map->targetFixedSizeInWords;
|
||||||
|
reinterpret_cast<uint32_t*>(dst + (TargetBytesPerWord * 2))
|
||||||
|
[offset / 32] |= static_cast<uint32_t>(1) << (offset % 32);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copy(t, typeMaps, p, dst);
|
||||||
|
}
|
||||||
|
|
||||||
if (DebugNativeTarget) {
|
if (DebugNativeTarget) {
|
||||||
expect(t, targetSize(t, typeMaps, p) == baseSize(t, p, objectClass(t, p)));
|
expect(t, targetSize(t, typeMaps, p) == baseSize(t, p, objectClass(t, p)));
|
||||||
expect(t, nonObjectsEqual(map, src, dst));
|
expect(t, nonObjectsEqual
|
||||||
|
(typeMap(t, typeMaps, p), reinterpret_cast<uint8_t*>(p), dst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapWalker*
|
HeapWalker*
|
||||||
makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap,
|
||||||
unsigned capacity, object constants, object typeMaps)
|
target_uintptr_t* map, unsigned capacity, object constants,
|
||||||
|
object typeMaps)
|
||||||
{
|
{
|
||||||
class Visitor: public HeapVisitor {
|
class Visitor: public HeapVisitor {
|
||||||
public:
|
public:
|
||||||
Visitor(Thread* t, object typeMaps, uintptr_t* heap,
|
Visitor(Thread* t, object typeMaps, target_uintptr_t* heap,
|
||||||
uintptr_t* map, unsigned capacity):
|
target_uintptr_t* map, unsigned capacity):
|
||||||
t(t), typeMaps(typeMaps), currentObject(0), currentNumber(0),
|
t(t), typeMaps(typeMaps), currentObject(0), currentNumber(0),
|
||||||
currentOffset(0), heap(heap), map(map), position(0), capacity(capacity)
|
currentOffset(0), heap(heap), map(map), position(0), capacity(capacity)
|
||||||
{ }
|
{ }
|
||||||
@ -845,8 +1140,8 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
(t, typeMaps, currentObject, currentOffset * BytesPerWord)
|
(t, typeMaps, currentObject, currentOffset * BytesPerWord)
|
||||||
/ TargetBytesPerWord);
|
/ TargetBytesPerWord);
|
||||||
|
|
||||||
unsigned mark = heap[offset] & (~PointerMask);
|
unsigned mark = heap[offset] & (~TargetPointerMask);
|
||||||
unsigned value = number | (mark << BootShift);
|
unsigned value = number | (mark << TargetBootShift);
|
||||||
|
|
||||||
if (value) markBit(map, offset);
|
if (value) markBit(map, offset);
|
||||||
|
|
||||||
@ -860,7 +1155,8 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
|
|
||||||
virtual unsigned visitNew(object p) {
|
virtual unsigned visitNew(object p) {
|
||||||
if (p) {
|
if (p) {
|
||||||
unsigned size = targetSize(t, typeMaps, p);
|
unsigned size = targetSize
|
||||||
|
(t, typeMaps, currentObject, currentOffset, p);
|
||||||
|
|
||||||
unsigned number;
|
unsigned number;
|
||||||
if ((currentObject
|
if ((currentObject
|
||||||
@ -877,7 +1173,7 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
|
|
||||||
target_uintptr_t* dst = heap + position + TargetFixieSizeInWords;
|
target_uintptr_t* dst = heap + position + TargetFixieSizeInWords;
|
||||||
|
|
||||||
unsigned maskSize = ceiling(size, TargetBytesPerWord);
|
unsigned maskSize = ceiling(size, TargetBitsPerWord);
|
||||||
|
|
||||||
unsigned total = TargetFixieSizeInWords + size + maskSize;
|
unsigned total = TargetFixieSizeInWords + size + maskSize;
|
||||||
|
|
||||||
@ -897,7 +1193,8 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
memcpy(reinterpret_cast<uint8_t*>(heap + position)
|
memcpy(reinterpret_cast<uint8_t*>(heap + position)
|
||||||
+ TargetFixieSize, &targetSize, 4);
|
+ TargetFixieSize, &targetSize, 4);
|
||||||
|
|
||||||
copy(t, typeMaps, p, reinterpret_cast<uint8_t*>(dst));
|
copy(t, typeMaps, currentObject, currentOffset, p,
|
||||||
|
reinterpret_cast<uint8_t*>(dst));
|
||||||
|
|
||||||
dst[0] |= FixedMark;
|
dst[0] |= FixedMark;
|
||||||
|
|
||||||
@ -909,7 +1206,8 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
|
|||||||
} else {
|
} else {
|
||||||
expect(t, position + size < capacity);
|
expect(t, position + size < capacity);
|
||||||
|
|
||||||
copy(t, typeMaps, p, reinterpret_cast<uint8_t*>(heap + position));
|
copy(t, typeMaps, currentObject, currentOffset, p,
|
||||||
|
reinterpret_cast<uint8_t*>(heap + position));
|
||||||
|
|
||||||
number = position + 1;
|
number = position + 1;
|
||||||
position += size;
|
position += size;
|
||||||
@ -970,15 +1268,21 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap,
|
|||||||
{
|
{
|
||||||
void* location;
|
void* location;
|
||||||
bool flat = pl->resolve(0, &location);
|
bool flat = pl->resolve(0, &location);
|
||||||
target_uintptr_t offset = target | BootHeapOffset;
|
target_uintptr_t offset = target | TargetBootHeapOffset;
|
||||||
if (flat) {
|
if (flat) {
|
||||||
offset |= BootFlatConstant;
|
offset |= TargetBootFlatConstant;
|
||||||
}
|
}
|
||||||
memcpy(location, &offset, TargetBytesPerWord);
|
memcpy(location, &offset, TargetBytesPerWord);
|
||||||
|
|
||||||
expect(t, reinterpret_cast<intptr_t>(location)
|
expect(t, reinterpret_cast<intptr_t>(location)
|
||||||
>= reinterpret_cast<intptr_t>(code));
|
>= reinterpret_cast<intptr_t>(code));
|
||||||
|
|
||||||
|
// fprintf(stderr, "mark constant %d %d\n",
|
||||||
|
// static_cast<unsigned>
|
||||||
|
// (reinterpret_cast<intptr_t>(location)
|
||||||
|
// - reinterpret_cast<intptr_t>(code)),
|
||||||
|
// static_cast<unsigned>(offset));
|
||||||
|
|
||||||
markBit(codeMap, reinterpret_cast<intptr_t>(location)
|
markBit(codeMap, reinterpret_cast<intptr_t>(location)
|
||||||
- reinterpret_cast<intptr_t>(code));
|
- reinterpret_cast<intptr_t>(code));
|
||||||
}
|
}
|
||||||
@ -1014,12 +1318,6 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
typeMaps = makeHashMap(t, 0, 0);
|
typeMaps = makeHashMap(t, 0, 0);
|
||||||
PROTECT(t, typeMaps);
|
PROTECT(t, typeMaps);
|
||||||
|
|
||||||
constants = makeCodeImage
|
|
||||||
(t, &zone, image, code, codeMap, className, methodName, methodSpec,
|
|
||||||
typeMaps);
|
|
||||||
|
|
||||||
PROTECT(t, constants);
|
|
||||||
|
|
||||||
#include "type-maps.cpp"
|
#include "type-maps.cpp"
|
||||||
|
|
||||||
for (unsigned i = 0; i < arrayLength(t, t->m->types); ++i) {
|
for (unsigned i = 0; i < arrayLength(t, t->m->types); ++i) {
|
||||||
@ -1030,21 +1328,26 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
}
|
}
|
||||||
++ count;
|
++ count;
|
||||||
|
|
||||||
Type types[count];
|
Field fields[count];
|
||||||
types[0] = Type_object;
|
|
||||||
unsigned buildOffsets[count];
|
new (fields) Field(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord);
|
||||||
buildOffsets[0] = 0;
|
|
||||||
unsigned buildOffset = BytesPerWord;
|
unsigned buildOffset = BytesPerWord;
|
||||||
unsigned targetOffsets[count];
|
|
||||||
targetOffsets[0] = 0;
|
|
||||||
unsigned targetOffset = TargetBytesPerWord;
|
unsigned targetOffset = TargetBytesPerWord;
|
||||||
bool sawArray = false;
|
bool sawArray = false;
|
||||||
unsigned buildSize = BytesPerWord;
|
Type type;
|
||||||
unsigned targetSize = TargetBytesPerWord;
|
unsigned buildSize;
|
||||||
|
unsigned targetSize;
|
||||||
for (unsigned j = 1; j < count; ++j) {
|
for (unsigned j = 1; j < count; ++j) {
|
||||||
switch (source[j - 1]) {
|
switch (source[j - 1]) {
|
||||||
case Type_object:
|
case Type_object:
|
||||||
types[j] = Type_object;
|
type = Type_object;
|
||||||
|
buildSize = BytesPerWord;
|
||||||
|
targetSize = TargetBytesPerWord;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_object_nogc:
|
||||||
|
type = Type_object_nogc;
|
||||||
buildSize = BytesPerWord;
|
buildSize = BytesPerWord;
|
||||||
targetSize = TargetBytesPerWord;
|
targetSize = TargetBytesPerWord;
|
||||||
break;
|
break;
|
||||||
@ -1052,39 +1355,39 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
case Type_word:
|
case Type_word:
|
||||||
case Type_intptr_t:
|
case Type_intptr_t:
|
||||||
case Type_uintptr_t:
|
case Type_uintptr_t:
|
||||||
types[j] = Type_intptr_t;
|
type = Type_intptr_t;
|
||||||
buildSize = BytesPerWord;
|
buildSize = BytesPerWord;
|
||||||
targetSize = TargetBytesPerWord;
|
targetSize = TargetBytesPerWord;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_int8_t:
|
case Type_int8_t:
|
||||||
case Type_uint8_t:
|
case Type_uint8_t:
|
||||||
types[j] = Type_int8_t;
|
type = Type_int8_t;
|
||||||
buildSize = targetSize = 1;
|
buildSize = targetSize = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_int16_t:
|
case Type_int16_t:
|
||||||
case Type_uint16_t:
|
case Type_uint16_t:
|
||||||
types[j] = Type_int16_t;
|
type = Type_int16_t;
|
||||||
buildSize = targetSize = 2;
|
buildSize = targetSize = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_int32_t:
|
case Type_int32_t:
|
||||||
case Type_uint32_t:
|
case Type_uint32_t:
|
||||||
case Type_float:
|
case Type_float:
|
||||||
types[j] = Type_int32_t;
|
type = Type_int32_t;
|
||||||
buildSize = targetSize = 4;
|
buildSize = targetSize = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_int64_t:
|
case Type_int64_t:
|
||||||
case Type_uint64_t:
|
case Type_uint64_t:
|
||||||
case Type_double:
|
case Type_double:
|
||||||
types[j] = Type_int64_t;
|
type = Type_int64_t;
|
||||||
buildSize = targetSize = 8;
|
buildSize = targetSize = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type_array:
|
case Type_array:
|
||||||
types[j] = Type_none;
|
type = Type_none;
|
||||||
buildSize = targetSize = 0;
|
buildSize = targetSize = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1100,16 +1403,14 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
++ buildOffset;
|
++ buildOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildOffsets[j] = buildOffset;
|
|
||||||
|
|
||||||
buildOffset += buildSize;
|
|
||||||
|
|
||||||
while (targetOffset % targetSize) {
|
while (targetOffset % targetSize) {
|
||||||
++ targetOffset;
|
++ targetOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetOffsets[j] = targetOffset;
|
new (fields + j) Field
|
||||||
|
(type, buildOffset, buildSize, targetOffset, targetSize);
|
||||||
|
|
||||||
|
buildOffset += buildSize;
|
||||||
targetOffset += targetSize;
|
targetOffset += targetSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1120,7 +1421,7 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
unsigned targetArrayElementSize;
|
unsigned targetArrayElementSize;
|
||||||
if (sawArray) {
|
if (sawArray) {
|
||||||
fixedFieldCount = count - 2;
|
fixedFieldCount = count - 2;
|
||||||
arrayElementType = types[count - 1];
|
arrayElementType = type;
|
||||||
buildArrayElementSize = buildSize;
|
buildArrayElementSize = buildSize;
|
||||||
targetArrayElementSize = targetSize;
|
targetArrayElementSize = targetSize;
|
||||||
} else {
|
} else {
|
||||||
@ -1141,19 +1442,27 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
targetArrayElementSize, arrayElementType);
|
targetArrayElementSize, arrayElementType);
|
||||||
|
|
||||||
for (unsigned j = 0; j < fixedFieldCount; ++j) {
|
for (unsigned j = 0; j < fixedFieldCount; ++j) {
|
||||||
expect(t, buildOffsets[j] < map->buildFixedSizeInWords * BytesPerWord);
|
Field* f = fields + j;
|
||||||
|
|
||||||
map->targetFixedOffsets()[buildOffsets[j]] = targetOffsets[j];
|
expect(t, f->buildOffset
|
||||||
|
< map->buildFixedSizeInWords * BytesPerWord);
|
||||||
|
|
||||||
new (map->fixedFields() + j) Field
|
map->targetFixedOffsets()[f->buildOffset] = f->targetOffset;
|
||||||
(types[j], buildOffsets[j], targetOffsets[j]);
|
|
||||||
|
map->fixedFields()[j] = *f;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashMapInsertOrReplace
|
hashMapInsert
|
||||||
(t, typeMaps, type(t, static_cast<Machine::Type>(i)), array,
|
(t, typeMaps, vm::type(t, static_cast<Machine::Type>(i)), array,
|
||||||
objectHash, objectEqual);
|
objectHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constants = makeCodeImage
|
||||||
|
(t, &zone, image, code, codeMap, className, methodName, methodSpec,
|
||||||
|
typeMaps);
|
||||||
|
|
||||||
|
PROTECT(t, constants);
|
||||||
|
|
||||||
// these roots will not be used when the bootimage is loaded, so
|
// these roots will not be used when the bootimage is loaded, so
|
||||||
// there's no need to preserve them:
|
// there's no need to preserve them:
|
||||||
setRoot(t, Machine::PoolMap, 0);
|
setRoot(t, Machine::PoolMap, 0);
|
||||||
@ -1217,9 +1526,10 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t* heap = static_cast<uintptr_t*>
|
target_uintptr_t* heap = static_cast<target_uintptr_t*>
|
||||||
(t->m->heap->allocate(HeapCapacity));
|
(t->m->heap->allocate(HeapCapacity));
|
||||||
uintptr_t* heapMap = static_cast<uintptr_t*>
|
|
||||||
|
target_uintptr_t* heapMap = static_cast<target_uintptr_t*>
|
||||||
(t->m->heap->allocate(heapMapSize(HeapCapacity)));
|
(t->m->heap->allocate(heapMapSize(HeapCapacity)));
|
||||||
memset(heapMap, 0, heapMapSize(HeapCapacity));
|
memset(heapMap, 0, heapMapSize(HeapCapacity));
|
||||||
|
|
||||||
@ -1275,7 +1585,6 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
heapWalker->dispose();
|
heapWalker->dispose();
|
||||||
|
|
||||||
image->magic = BootImage::Magic;
|
image->magic = BootImage::Magic;
|
||||||
image->codeBase = reinterpret_cast<uintptr_t>(code);
|
|
||||||
|
|
||||||
fprintf(stderr, "class count %d string count %d call count %d\n"
|
fprintf(stderr, "class count %d string count %d call count %d\n"
|
||||||
"heap size %d code size %d\n",
|
"heap size %d code size %d\n",
|
||||||
@ -1301,11 +1610,15 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
|
|||||||
++ offset;
|
++ offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(heapMap, pad(heapMapSize(image->heapSize)), 1, out);
|
fwrite
|
||||||
fwrite(heap, pad(image->heapSize), 1, out);
|
(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord), 1, out);
|
||||||
|
|
||||||
fwrite(codeMap, pad(codeMapSize(image->codeSize)), 1, out);
|
fwrite(heap, pad(image->heapSize, TargetBytesPerWord), 1, out);
|
||||||
fwrite(code, pad(image->codeSize), 1, out);
|
|
||||||
|
fwrite
|
||||||
|
(codeMap, pad(codeMapSize(image->codeSize), TargetBytesPerWord), 1, out);
|
||||||
|
|
||||||
|
fwrite(code, pad(image->codeSize, TargetBytesPerWord), 1, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
102
src/bootimage.h
102
src/bootimage.h
@ -12,16 +12,11 @@
|
|||||||
#define BOOTIMAGE_H
|
#define BOOTIMAGE_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "target.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
const unsigned BootMask = (~static_cast<unsigned>(0)) / BytesPerWord;
|
|
||||||
|
|
||||||
const unsigned BootShift = 32 - log(BytesPerWord);
|
|
||||||
|
|
||||||
const unsigned BootFlatConstant = 1 << BootShift;
|
|
||||||
const unsigned BootHeapOffset = 1 << (BootShift + 1);
|
|
||||||
|
|
||||||
class BootImage {
|
class BootImage {
|
||||||
public:
|
public:
|
||||||
class Thunk {
|
class Thunk {
|
||||||
@ -30,14 +25,14 @@ class BootImage {
|
|||||||
start(0), frameSavedOffset(0), length(0)
|
start(0), frameSavedOffset(0), length(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Thunk(unsigned start, unsigned frameSavedOffset, unsigned length):
|
Thunk(uint32_t start, uint32_t frameSavedOffset, uint32_t length):
|
||||||
start(start), frameSavedOffset(frameSavedOffset), length(length)
|
start(start), frameSavedOffset(frameSavedOffset), length(length)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
unsigned start;
|
uint32_t start;
|
||||||
unsigned frameSavedOffset;
|
uint32_t frameSavedOffset;
|
||||||
unsigned length;
|
uint32_t length;
|
||||||
};
|
} PACKED;
|
||||||
|
|
||||||
class ThunkCollection {
|
class ThunkCollection {
|
||||||
public:
|
public:
|
||||||
@ -47,63 +42,56 @@ class BootImage {
|
|||||||
Thunk aioob;
|
Thunk aioob;
|
||||||
Thunk stackOverflow;
|
Thunk stackOverflow;
|
||||||
Thunk table;
|
Thunk table;
|
||||||
};
|
} PACKED;
|
||||||
|
|
||||||
static const unsigned Magic = 0x22377322;
|
static const uint32_t Magic = 0x22377322;
|
||||||
|
|
||||||
unsigned magic;
|
uint32_t magic;
|
||||||
|
|
||||||
unsigned heapSize;
|
uint32_t heapSize;
|
||||||
unsigned codeSize;
|
uint32_t codeSize;
|
||||||
|
|
||||||
unsigned bootClassCount;
|
uint32_t bootClassCount;
|
||||||
unsigned appClassCount;
|
uint32_t appClassCount;
|
||||||
unsigned stringCount;
|
uint32_t stringCount;
|
||||||
unsigned callCount;
|
uint32_t callCount;
|
||||||
|
|
||||||
unsigned bootLoader;
|
uint32_t bootLoader;
|
||||||
unsigned appLoader;
|
uint32_t appLoader;
|
||||||
unsigned types;
|
uint32_t types;
|
||||||
unsigned methodTree;
|
uint32_t methodTree;
|
||||||
unsigned methodTreeSentinal;
|
uint32_t methodTreeSentinal;
|
||||||
unsigned virtualThunks;
|
uint32_t virtualThunks;
|
||||||
|
|
||||||
uintptr_t codeBase;
|
uint32_t compileMethodCall;
|
||||||
|
uint32_t compileVirtualMethodCall;
|
||||||
|
uint32_t invokeNativeCall;
|
||||||
|
uint32_t throwArrayIndexOutOfBoundsCall;
|
||||||
|
uint32_t throwStackOverflowCall;
|
||||||
|
|
||||||
ThunkCollection thunks;
|
#define THUNK(s) uint32_t s##Call;
|
||||||
|
|
||||||
unsigned compileMethodCall;
|
|
||||||
unsigned compileVirtualMethodCall;
|
|
||||||
unsigned invokeNativeCall;
|
|
||||||
unsigned throwArrayIndexOutOfBoundsCall;
|
|
||||||
unsigned throwStackOverflowCall;
|
|
||||||
|
|
||||||
#define THUNK(s) unsigned s##Call;
|
|
||||||
#include "thunks.cpp"
|
#include "thunks.cpp"
|
||||||
#undef THUNK
|
#undef THUNK
|
||||||
|
|
||||||
|
ThunkCollection thunks;
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
class OffsetResolver {
|
||||||
|
public:
|
||||||
|
virtual unsigned fieldOffset(Thread*, object) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline unsigned
|
#define NAME(x) Target##x
|
||||||
codeMapSize(unsigned codeSize)
|
#define LABEL(x) target_##x
|
||||||
{
|
#include "bootimage-template.cpp"
|
||||||
return ceiling(codeSize, BitsPerWord) * BytesPerWord;
|
#undef LABEL
|
||||||
}
|
#undef NAME
|
||||||
|
|
||||||
inline unsigned
|
#define NAME(x) x
|
||||||
heapMapSize(unsigned heapSize)
|
#define LABEL(x) x
|
||||||
{
|
#include "bootimage-template.cpp"
|
||||||
return ceiling(heapSize, BitsPerWord * BytesPerWord) * BytesPerWord;
|
#undef LABEL
|
||||||
}
|
#undef NAME
|
||||||
|
|
||||||
inline object
|
|
||||||
bootObject(uintptr_t* heap, unsigned offset)
|
|
||||||
{
|
|
||||||
if (offset) {
|
|
||||||
return reinterpret_cast<object>(heap + offset - 1);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ typedef unsigned __int64 uint64_t;
|
|||||||
|
|
||||||
# define NO_RETURN __declspec(noreturn)
|
# define NO_RETURN __declspec(noreturn)
|
||||||
|
|
||||||
|
# define PACKED
|
||||||
|
|
||||||
# define PLATFORM_WINDOWS
|
# define PLATFORM_WINDOWS
|
||||||
|
|
||||||
# ifdef _M_IX86
|
# ifdef _M_IX86
|
||||||
@ -76,6 +78,8 @@ typedef intptr_t intptr_alias_t;
|
|||||||
|
|
||||||
# define NO_RETURN __attribute__((noreturn))
|
# define NO_RETURN __attribute__((noreturn))
|
||||||
|
|
||||||
|
# define PACKED __attribute__((packed))
|
||||||
|
|
||||||
# ifdef __MINGW32__
|
# ifdef __MINGW32__
|
||||||
# define PLATFORM_WINDOWS
|
# define PLATFORM_WINDOWS
|
||||||
# endif
|
# endif
|
||||||
|
214
src/compile.cpp
214
src/compile.cpp
@ -336,7 +336,7 @@ setRoot(Thread* t, Root root, object value);
|
|||||||
unsigned
|
unsigned
|
||||||
compiledSize(intptr_t address)
|
compiledSize(intptr_t address)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<uintptr_t*>(address)[-1];
|
return reinterpret_cast<target_uintptr_t*>(address)[-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t
|
intptr_t
|
||||||
@ -956,9 +956,10 @@ class BootContext {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BootContext(Thread* t, object constants, object calls,
|
BootContext(Thread* t, object constants, object calls,
|
||||||
DelayedPromise* addresses, Zone* zone):
|
DelayedPromise* addresses, Zone* zone, OffsetResolver* resolver):
|
||||||
protector(t, this), constants(constants), calls(calls),
|
protector(t, this), constants(constants), calls(calls),
|
||||||
addresses(addresses), addressSentinal(addresses), zone(zone)
|
addresses(addresses), addressSentinal(addresses), zone(zone),
|
||||||
|
resolver(resolver)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
MyProtector protector;
|
MyProtector protector;
|
||||||
@ -967,6 +968,7 @@ class BootContext {
|
|||||||
DelayedPromise* addresses;
|
DelayedPromise* addresses;
|
||||||
DelayedPromise* addressSentinal;
|
DelayedPromise* addressSentinal;
|
||||||
Zone* zone;
|
Zone* zone;
|
||||||
|
OffsetResolver* resolver;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
@ -3309,7 +3311,7 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
|
|||||||
(TargetBytesPerWord, frame->addressOperand(returnAddressPromise),
|
(TargetBytesPerWord, frame->addressOperand(returnAddressPromise),
|
||||||
TargetBytesPerWord, c->memory
|
TargetBytesPerWord, c->memory
|
||||||
(c->register_(t->arch->thread()), Compiler::AddressType,
|
(c->register_(t->arch->thread()), Compiler::AddressType,
|
||||||
difference(&(t->tailAddress), t)));
|
TargetThreadTailAddress));
|
||||||
|
|
||||||
c->exit
|
c->exit
|
||||||
(c->constant
|
(c->constant
|
||||||
@ -3800,6 +3802,16 @@ intrinsic(MyThread* t, Frame* frame, object target)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
targetFieldOffset(Context* context, object field)
|
||||||
|
{
|
||||||
|
if (context->bootContext) {
|
||||||
|
return context->bootContext->resolver->fieldOffset(context->thread, field);
|
||||||
|
} else {
|
||||||
|
return fieldOffset(context->thread, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||||
int exceptionHandlerStart)
|
int exceptionHandlerStart)
|
||||||
@ -3861,7 +3873,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CheckArrayBounds) {
|
if (CheckArrayBounds) {
|
||||||
c->checkBounds(array, ArrayLength, index, aioobThunk(t));
|
c->checkBounds(array, TargetArrayLength, index, aioobThunk(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
@ -3869,7 +3881,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushObject
|
frame->pushObject
|
||||||
(c->load
|
(c->load
|
||||||
(TargetBytesPerWord, TargetBytesPerWord, c->memory
|
(TargetBytesPerWord, TargetBytesPerWord, c->memory
|
||||||
(array, Compiler::ObjectType, ArrayBody, index,
|
(array, Compiler::ObjectType, TargetArrayBody, index,
|
||||||
TargetBytesPerWord),
|
TargetBytesPerWord),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
@ -3878,7 +3890,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(array, Compiler::FloatType, ArrayBody, index, 4),
|
(array, Compiler::FloatType, TargetArrayBody, index, 4),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3886,7 +3898,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 4),
|
(array, Compiler::IntegerType, TargetArrayBody, index, 4),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3894,7 +3906,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(1, 1, c->memory
|
(1, 1, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 1),
|
(array, Compiler::IntegerType, TargetArrayBody, index, 1),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3902,7 +3914,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->loadz
|
(c->loadz
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 2),
|
(array, Compiler::IntegerType, TargetArrayBody, index, 2),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3910,21 +3922,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->load
|
(c->load
|
||||||
(8, 8, c->memory
|
(8, 8, c->memory
|
||||||
(array, Compiler::FloatType, ArrayBody, index, 8), 8));
|
(array, Compiler::FloatType, TargetArrayBody, index, 8), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case laload:
|
case laload:
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->load
|
(c->load
|
||||||
(8, 8, c->memory
|
(8, 8, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 8), 8));
|
(array, Compiler::IntegerType, TargetArrayBody, index, 8), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case saload:
|
case saload:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 2),
|
(array, Compiler::IntegerType, TargetArrayBody, index, 2),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3956,7 +3968,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CheckArrayBounds) {
|
if (CheckArrayBounds) {
|
||||||
c->checkBounds(array, ArrayLength, index, aioobThunk(t));
|
c->checkBounds(array, TargetArrayLength, index, aioobThunk(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
@ -3969,7 +3981,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::VoidType,
|
Compiler::VoidType,
|
||||||
4, c->register_(t->arch->thread()), array,
|
4, c->register_(t->arch->thread()), array,
|
||||||
c->add
|
c->add
|
||||||
(4, c->constant(ArrayBody, Compiler::IntegerType),
|
(4, c->constant(TargetArrayBody, Compiler::IntegerType),
|
||||||
c->shl
|
c->shl
|
||||||
(4, c->constant(log(TargetBytesPerWord), Compiler::IntegerType),
|
(4, c->constant(log(TargetBytesPerWord), Compiler::IntegerType),
|
||||||
index)),
|
index)),
|
||||||
@ -3979,38 +3991,38 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case fastore:
|
case fastore:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(array, Compiler::FloatType, ArrayBody, index, 4));
|
(array, Compiler::FloatType, TargetArrayBody, index, 4));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iastore:
|
case iastore:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 4));
|
(array, Compiler::IntegerType, TargetArrayBody, index, 4));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bastore:
|
case bastore:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 1, c->memory
|
(TargetBytesPerWord, value, 1, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 1));
|
(array, Compiler::IntegerType, TargetArrayBody, index, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case castore:
|
case castore:
|
||||||
case sastore:
|
case sastore:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 2, c->memory
|
(TargetBytesPerWord, value, 2, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 2));
|
(array, Compiler::IntegerType, TargetArrayBody, index, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dastore:
|
case dastore:
|
||||||
c->store
|
c->store
|
||||||
(8, value, 8, c->memory
|
(8, value, 8, c->memory
|
||||||
(array, Compiler::FloatType, ArrayBody, index, 8));
|
(array, Compiler::FloatType, TargetArrayBody, index, 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lastore:
|
case lastore:
|
||||||
c->store
|
c->store
|
||||||
(8, value, 8, c->memory
|
(8, value, 8, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 8));
|
(array, Compiler::IntegerType, TargetArrayBody, index, 8));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4082,7 +4094,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(TargetBytesPerWord, TargetBytesPerWord,
|
(TargetBytesPerWord, TargetBytesPerWord,
|
||||||
c->memory
|
c->memory
|
||||||
(frame->popObject(), Compiler::IntegerType, ArrayLength, 0, 1),
|
(frame->popObject(), Compiler::IntegerType,
|
||||||
|
TargetArrayLength, 0, 1),
|
||||||
TargetBytesPerWord));
|
TargetBytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4425,54 +4438,56 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(1, 1, c->memory
|
(1, 1, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
TargetBytesPerWord));
|
(context, field), 0, 1), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->loadz
|
(c->loadz
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
TargetBytesPerWord));
|
(context, field), 0, 1), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ShortField:
|
case ShortField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
TargetBytesPerWord));
|
(context, field), 0, 1), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FloatField:
|
case FloatField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::FloatType, targetFieldOffset
|
||||||
TargetBytesPerWord));
|
(context, field), 0, 1), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IntField:
|
case IntField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
TargetBytesPerWord));
|
(context, field), 0, 1), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->load
|
(c->load
|
||||||
(8, 8, c->memory
|
(8, 8, c->memory
|
||||||
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1), 8));
|
(table, Compiler::FloatType, targetFieldOffset
|
||||||
|
(context, field), 0, 1), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LongField:
|
case LongField:
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->load
|
(c->load
|
||||||
(8, 8, c->memory
|
(8, 8, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), 8));
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
|
(context, field), 0, 1), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
@ -4480,8 +4495,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(TargetBytesPerWord, TargetBytesPerWord,
|
(TargetBytesPerWord, TargetBytesPerWord,
|
||||||
c->memory
|
c->memory
|
||||||
(table, Compiler::ObjectType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::ObjectType, targetFieldOffset
|
||||||
TargetBytesPerWord));
|
(context, field), 0, 1), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -4974,8 +4989,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
if (LIKELY(methodVirtual(t, target))) {
|
if (LIKELY(methodVirtual(t, target))) {
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, target);
|
unsigned parameterFootprint = methodParameterFootprint(t, target);
|
||||||
|
|
||||||
unsigned offset = ClassVtable
|
unsigned offset = TargetClassVtable
|
||||||
+ (methodOffset(t, target) * BytesPerWord);
|
+ (methodOffset(t, target) * TargetBytesPerWord);
|
||||||
|
|
||||||
Compiler::Operand* instance = c->peek(1, parameterFootprint - 1);
|
Compiler::Operand* instance = c->peek(1, parameterFootprint - 1);
|
||||||
|
|
||||||
@ -4985,7 +5000,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->memory
|
(c->memory
|
||||||
(c->and_
|
(c->and_
|
||||||
(TargetBytesPerWord, c->constant
|
(TargetBytesPerWord, c->constant
|
||||||
(PointerMask, Compiler::IntegerType),
|
(TargetPointerMask, Compiler::IntegerType),
|
||||||
c->memory(instance, Compiler::ObjectType, 0, 0, 1)),
|
c->memory(instance, Compiler::ObjectType, 0, 0, 1)),
|
||||||
Compiler::ObjectType, offset, 0, 1),
|
Compiler::ObjectType, offset, 0, 1),
|
||||||
tailCall ? Compiler::TailJump : 0,
|
tailCall ? Compiler::TailJump : 0,
|
||||||
@ -5635,38 +5650,44 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case BooleanField:
|
case BooleanField:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 1, c->memory
|
(TargetBytesPerWord, value, 1, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
|
(context, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
case ShortField:
|
case ShortField:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 2, c->memory
|
(TargetBytesPerWord, value, 2, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
|
(context, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FloatField:
|
case FloatField:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::FloatType, targetFieldOffset
|
||||||
|
(context, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IntField:
|
case IntField:
|
||||||
c->store
|
c->store
|
||||||
(TargetBytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
|
(context, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
c->store
|
c->store
|
||||||
(8, value, 8, c->memory
|
(8, value, 8, c->memory
|
||||||
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::FloatType, targetFieldOffset
|
||||||
|
(context, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LongField:
|
case LongField:
|
||||||
c->store
|
c->store
|
||||||
(8, value, 8, c->memory
|
(8, value, 8, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, targetFieldOffset
|
||||||
|
(context, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
@ -5679,14 +5700,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
0,
|
0,
|
||||||
Compiler::VoidType,
|
Compiler::VoidType,
|
||||||
4, c->register_(t->arch->thread()), table,
|
4, c->register_(t->arch->thread()), table,
|
||||||
c->constant(fieldOffset(t, field), Compiler::IntegerType),
|
c->constant(targetFieldOffset(context, field),
|
||||||
|
Compiler::IntegerType),
|
||||||
value);
|
value);
|
||||||
} else {
|
} else {
|
||||||
c->call
|
c->call
|
||||||
(c->constant(getThunk(t, setThunk), Compiler::AddressType),
|
(c->constant(getThunk(t, setThunk), Compiler::AddressType),
|
||||||
0, 0, 0, Compiler::VoidType,
|
0, 0, 0, Compiler::VoidType,
|
||||||
4, c->register_(t->arch->thread()), table,
|
4, c->register_(t->arch->thread()), table,
|
||||||
c->constant(fieldOffset(t, field), Compiler::IntegerType),
|
c->constant(targetFieldOffset(context, field),
|
||||||
|
Compiler::IntegerType),
|
||||||
value);
|
value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -6797,7 +6820,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
// of cycles if another thread compiles the same method in parallel,
|
// of cycles if another thread compiles the same method in parallel,
|
||||||
// which might be mitigated by fine-grained, per-method locking):
|
// which might be mitigated by fine-grained, per-method locking):
|
||||||
c->compile(context->leaf ? 0 : stackOverflowThunk(t),
|
c->compile(context->leaf ? 0 : stackOverflowThunk(t),
|
||||||
difference(&(t->stackLimit), t));
|
TargetThreadStackLimit);
|
||||||
|
|
||||||
// we must acquire the class lock here at the latest
|
// we must acquire the class lock here at the latest
|
||||||
|
|
||||||
@ -6806,7 +6829,8 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
|
|
||||||
unsigned total = pad(codeSize) + pad(c->poolSize()) + TargetBytesPerWord;
|
unsigned total = pad(codeSize) + pad(c->poolSize()) + TargetBytesPerWord;
|
||||||
|
|
||||||
uintptr_t* code = static_cast<uintptr_t*>(allocator->allocate(total));
|
target_uintptr_t* code = static_cast<target_uintptr_t*>
|
||||||
|
(allocator->allocate(total));
|
||||||
code[0] = codeSize;
|
code[0] = codeSize;
|
||||||
uint8_t* start = reinterpret_cast<uint8_t*>(code + 1);
|
uint8_t* start = reinterpret_cast<uint8_t*>(code + 1);
|
||||||
|
|
||||||
@ -6817,8 +6841,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
if (context->objectPool) {
|
if (context->objectPool) {
|
||||||
object pool = allocate3
|
object pool = allocate3
|
||||||
(t, allocator, Machine::ImmortalAllocation,
|
(t, allocator, Machine::ImmortalAllocation,
|
||||||
FixedSizeOfArray
|
FixedSizeOfArray + ((context->objectPoolCount + 1) * BytesPerWord),
|
||||||
+ ((context->objectPoolCount + 1) * TargetBytesPerWord),
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
initArray(t, pool, context->objectPoolCount + 1);
|
initArray(t, pool, context->objectPoolCount + 1);
|
||||||
@ -6829,7 +6852,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
|
|
||||||
unsigned i = 1;
|
unsigned i = 1;
|
||||||
for (PoolElement* p = context->objectPool; p; p = p->next) {
|
for (PoolElement* p = context->objectPool; p; p = p->next) {
|
||||||
unsigned offset = ArrayBody + ((i++) * TargetBytesPerWord);
|
unsigned offset = ArrayBody + ((i++) * BytesPerWord);
|
||||||
|
|
||||||
p->address = reinterpret_cast<uintptr_t>(pool) + offset;
|
p->address = reinterpret_cast<uintptr_t>(pool) + offset;
|
||||||
|
|
||||||
@ -8318,13 +8341,30 @@ class MyProcessor: public Processor {
|
|||||||
t->init();
|
t->init();
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
fprintf(stderr, "%d\n", difference(&(t->stack), t));
|
fprintf(stderr, "stack %d\n",
|
||||||
fprintf(stderr, "%d\n", difference(&(t->scratch), t));
|
difference(&(t->stack), t));
|
||||||
fprintf(stderr, "%d\n", difference(&(t->continuation), t));
|
fprintf(stderr, "scratch %d\n",
|
||||||
fprintf(stderr, "%d\n", difference(&(t->exception), t));
|
difference(&(t->scratch), t));
|
||||||
fprintf(stderr, "%d\n", difference(&(t->exceptionStackAdjustment), t));
|
fprintf(stderr, "continuation %d\n",
|
||||||
fprintf(stderr, "%d\n", difference(&(t->exceptionOffset), t));
|
difference(&(t->continuation), t));
|
||||||
fprintf(stderr, "%d\n", difference(&(t->exceptionHandler), t));
|
fprintf(stderr, "exception %d\n",
|
||||||
|
difference(&(t->exception), t));
|
||||||
|
fprintf(stderr, "exceptionStackAdjustment %d\n",
|
||||||
|
difference(&(t->exceptionStackAdjustment), t));
|
||||||
|
fprintf(stderr, "exceptionOffset %d\n",
|
||||||
|
difference(&(t->exceptionOffset), t));
|
||||||
|
fprintf(stderr, "exceptionHandler %d\n",
|
||||||
|
difference(&(t->exceptionHandler), t));
|
||||||
|
fprintf(stderr, "tailAddress %d\n",
|
||||||
|
difference(&(t->tailAddress), t));
|
||||||
|
fprintf(stderr, "stackLimit %d\n",
|
||||||
|
difference(&(t->stackLimit), t));
|
||||||
|
fprintf(stderr, "ip %d\n",
|
||||||
|
difference(&(t->ip), t));
|
||||||
|
fprintf(stderr, "virtualCallTarget %d\n",
|
||||||
|
difference(&(t->virtualCallTarget), t));
|
||||||
|
fprintf(stderr, "virtualCallIndex %d\n",
|
||||||
|
difference(&(t->virtualCallIndex), t));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8671,10 +8711,10 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
virtual void compileMethod(Thread* vmt, Zone* zone, object* constants,
|
virtual void compileMethod(Thread* vmt, Zone* zone, object* constants,
|
||||||
object* calls, DelayedPromise** addresses,
|
object* calls, DelayedPromise** addresses,
|
||||||
object method)
|
object method, OffsetResolver* resolver)
|
||||||
{
|
{
|
||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
BootContext bootContext(t, *constants, *calls, *addresses, zone);
|
BootContext bootContext(t, *constants, *calls, *addresses, zone, resolver);
|
||||||
|
|
||||||
compile(t, &codeAllocator, &bootContext, method);
|
compile(t, &codeAllocator, &bootContext, method);
|
||||||
|
|
||||||
@ -8689,6 +8729,17 @@ class MyProcessor: public Processor {
|
|||||||
bootImage->virtualThunks = w->visitRoot(root(t, VirtualThunks));
|
bootImage->virtualThunks = w->visitRoot(root(t, VirtualThunks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void normalizeVirtualThunks(Thread* t) {
|
||||||
|
for (unsigned i = 0; i < wordArrayLength(t, root(t, VirtualThunks));
|
||||||
|
i += 2)
|
||||||
|
{
|
||||||
|
if (wordArrayBody(t, root(t, VirtualThunks), i)) {
|
||||||
|
wordArrayBody(t, root(t, VirtualThunks), i)
|
||||||
|
-= reinterpret_cast<uintptr_t>(codeAllocator.base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual unsigned* makeCallTable(Thread* t, HeapWalker* w) {
|
virtual unsigned* makeCallTable(Thread* t, HeapWalker* w) {
|
||||||
bootImage->codeSize = codeAllocator.offset;
|
bootImage->codeSize = codeAllocator.offset;
|
||||||
bootImage->callCount = callTableSize;
|
bootImage->callCount = callTableSize;
|
||||||
@ -8704,7 +8755,7 @@ class MyProcessor: public Processor {
|
|||||||
table[index++] = callNodeAddress(t, p)
|
table[index++] = callNodeAddress(t, p)
|
||||||
- reinterpret_cast<uintptr_t>(codeAllocator.base);
|
- reinterpret_cast<uintptr_t>(codeAllocator.base);
|
||||||
table[index++] = w->map()->find(callNodeTarget(t, p))
|
table[index++] = w->map()->find(callNodeTarget(t, p))
|
||||||
| (static_cast<unsigned>(callNodeFlags(t, p)) << BootShift);
|
| (static_cast<unsigned>(callNodeFlags(t, p)) << TargetBootShift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8989,7 +9040,8 @@ insertCallNode(MyThread* t, object node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
makeClassMap(Thread* t, unsigned* table, unsigned count, uintptr_t* heap)
|
makeClassMap(Thread* t, unsigned* table, unsigned count,
|
||||||
|
uintptr_t* heap)
|
||||||
{
|
{
|
||||||
object array = makeArray(t, nextPowerOfTwo(count));
|
object array = makeArray(t, nextPowerOfTwo(count));
|
||||||
object map = makeHashMap(t, 0, array);
|
object map = makeHashMap(t, 0, array);
|
||||||
@ -9068,6 +9120,7 @@ fixupHeap(MyThread* t UNUSED, uintptr_t* map, unsigned size, uintptr_t* heap)
|
|||||||
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* p = heap + index;
|
uintptr_t* p = heap + index;
|
||||||
assert(t, *p);
|
assert(t, *p);
|
||||||
|
|
||||||
@ -9103,6 +9156,10 @@ fixupCode(Thread* t, uintptr_t* map, unsigned size, uint8_t* code,
|
|||||||
if (oldValue & BootHeapOffset) {
|
if (oldValue & BootHeapOffset) {
|
||||||
newValue = reinterpret_cast<uintptr_t>
|
newValue = reinterpret_cast<uintptr_t>
|
||||||
(heap + (oldValue & BootMask) - 1);
|
(heap + (oldValue & BootMask) - 1);
|
||||||
|
|
||||||
|
// fprintf(stderr, "constant marked %d %d\n",
|
||||||
|
// index, static_cast<unsigned>(oldValue));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
newValue = reinterpret_cast<uintptr_t>
|
newValue = reinterpret_cast<uintptr_t>
|
||||||
(code + (oldValue & BootMask));
|
(code + (oldValue & BootMask));
|
||||||
@ -9130,12 +9187,11 @@ fixupMethods(Thread* t, object map, BootImage* image, uint8_t* code)
|
|||||||
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
||||||
object method = arrayBody(t, classMethodTable(t, c), i);
|
object method = arrayBody(t, classMethodTable(t, c), i);
|
||||||
if (methodCode(t, method)) {
|
if (methodCode(t, method)) {
|
||||||
assert(t, (methodCompiled(t, method) - image->codeBase)
|
assert(t, methodCompiled(t, method)
|
||||||
<= image->codeSize);
|
<= static_cast<int32_t>(image->codeSize));
|
||||||
|
|
||||||
codeCompiled(t, methodCode(t, method))
|
codeCompiled(t, methodCode(t, method))
|
||||||
= (methodCompiled(t, method) - image->codeBase)
|
= methodCompiled(t, method) + reinterpret_cast<uintptr_t>(code);
|
||||||
+ reinterpret_cast<uintptr_t>(code);
|
|
||||||
|
|
||||||
if (DebugCompile) {
|
if (DebugCompile) {
|
||||||
logCompile
|
logCompile
|
||||||
@ -9203,13 +9259,13 @@ fixupThunks(MyThread* t, BootImage* image, uint8_t* code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fixupVirtualThunks(MyThread* t, BootImage* image, uint8_t* code)
|
fixupVirtualThunks(MyThread* t, uint8_t* code)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < wordArrayLength(t, root(t, VirtualThunks)); i += 2)
|
for (unsigned i = 0; i < wordArrayLength(t, root(t, VirtualThunks)); i += 2)
|
||||||
{
|
{
|
||||||
if (wordArrayBody(t, root(t, VirtualThunks), i)) {
|
if (wordArrayBody(t, root(t, VirtualThunks), i)) {
|
||||||
wordArrayBody(t, root(t, VirtualThunks), i)
|
wordArrayBody(t, root(t, VirtualThunks), i)
|
||||||
= (wordArrayBody(t, root(t, VirtualThunks), i) - image->codeBase)
|
= wordArrayBody(t, root(t, VirtualThunks), i)
|
||||||
+ reinterpret_cast<uintptr_t>(code);
|
+ reinterpret_cast<uintptr_t>(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9293,7 +9349,7 @@ boot(MyThread* t, BootImage* image)
|
|||||||
|
|
||||||
fixupThunks(t, image, code);
|
fixupThunks(t, image, code);
|
||||||
|
|
||||||
fixupVirtualThunks(t, image, code);
|
fixupVirtualThunks(t, code);
|
||||||
|
|
||||||
fixupMethods
|
fixupMethods
|
||||||
(t, classLoaderMap(t, root(t, Machine::BootLoader)), image, code);
|
(t, classLoaderMap(t, root(t, Machine::BootLoader)), image, code);
|
||||||
@ -9337,7 +9393,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
|
|
||||||
{ Assembler* a = defaultContext.context.assembler;
|
{ Assembler* a = defaultContext.context.assembler;
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(TargetThreadStack, TargetThreadIp);
|
||||||
|
|
||||||
p->thunks.default_.frameSavedOffset = a->length();
|
p->thunks.default_.frameSavedOffset = a->length();
|
||||||
|
|
||||||
@ -9369,19 +9425,19 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
TargetBytesPerWord, RegisterOperand, &class_);
|
TargetBytesPerWord, RegisterOperand, &class_);
|
||||||
|
|
||||||
Assembler::Memory virtualCallTargetDst
|
Assembler::Memory virtualCallTargetDst
|
||||||
(t->arch->thread(), difference(&(t->virtualCallTarget), t));
|
(t->arch->thread(), TargetThreadVirtualCallTarget);
|
||||||
|
|
||||||
a->apply(Move, TargetBytesPerWord, RegisterOperand, &class_,
|
a->apply(Move, TargetBytesPerWord, RegisterOperand, &class_,
|
||||||
TargetBytesPerWord, MemoryOperand, &virtualCallTargetDst);
|
TargetBytesPerWord, MemoryOperand, &virtualCallTargetDst);
|
||||||
|
|
||||||
Assembler::Register index(t->arch->virtualCallIndex());
|
Assembler::Register index(t->arch->virtualCallIndex());
|
||||||
Assembler::Memory virtualCallIndex
|
Assembler::Memory virtualCallIndex
|
||||||
(t->arch->thread(), difference(&(t->virtualCallIndex), t));
|
(t->arch->thread(), TargetThreadVirtualCallIndex);
|
||||||
|
|
||||||
a->apply(Move, TargetBytesPerWord, RegisterOperand, &index,
|
a->apply(Move, TargetBytesPerWord, RegisterOperand, &index,
|
||||||
TargetBytesPerWord, MemoryOperand, &virtualCallIndex);
|
TargetBytesPerWord, MemoryOperand, &virtualCallIndex);
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(TargetThreadStack, TargetThreadIp);
|
||||||
|
|
||||||
p->thunks.defaultVirtual.frameSavedOffset = a->length();
|
p->thunks.defaultVirtual.frameSavedOffset = a->length();
|
||||||
|
|
||||||
@ -9403,7 +9459,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
|
|
||||||
{ Assembler* a = nativeContext.context.assembler;
|
{ Assembler* a = nativeContext.context.assembler;
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(TargetThreadStack, TargetThreadIp);
|
||||||
|
|
||||||
p->thunks.native.frameSavedOffset = a->length();
|
p->thunks.native.frameSavedOffset = a->length();
|
||||||
|
|
||||||
@ -9414,7 +9470,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
a->popFrameAndUpdateStackAndReturn
|
a->popFrameAndUpdateStackAndReturn
|
||||||
(t->arch->alignFrameSize(1), difference(&(t->stack), t));
|
(t->arch->alignFrameSize(1), TargetThreadStack);
|
||||||
|
|
||||||
p->thunks.native.length = a->endBlock(false)->resolve(0, 0);
|
p->thunks.native.length = a->endBlock(false)->resolve(0, 0);
|
||||||
}
|
}
|
||||||
@ -9423,7 +9479,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
|
|
||||||
{ Assembler* a = aioobContext.context.assembler;
|
{ Assembler* a = aioobContext.context.assembler;
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(TargetThreadStack, TargetThreadIp);
|
||||||
|
|
||||||
p->thunks.aioob.frameSavedOffset = a->length();
|
p->thunks.aioob.frameSavedOffset = a->length();
|
||||||
|
|
||||||
@ -9440,7 +9496,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
|
|
||||||
{ Assembler* a = stackOverflowContext.context.assembler;
|
{ Assembler* a = stackOverflowContext.context.assembler;
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(TargetThreadStack, TargetThreadIp);
|
||||||
|
|
||||||
p->thunks.stackOverflow.frameSavedOffset = a->length();
|
p->thunks.stackOverflow.frameSavedOffset = a->length();
|
||||||
|
|
||||||
@ -9457,7 +9513,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
|
|
||||||
{ Assembler* a = tableContext.context.assembler;
|
{ Assembler* a = tableContext.context.assembler;
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(TargetThreadStack, TargetThreadIp);
|
||||||
|
|
||||||
p->thunks.table.frameSavedOffset = a->length();
|
p->thunks.table.frameSavedOffset = a->length();
|
||||||
|
|
||||||
|
@ -469,7 +469,7 @@ class PoolPromise: public Promise {
|
|||||||
virtual int64_t value() {
|
virtual int64_t value() {
|
||||||
if (resolved()) {
|
if (resolved()) {
|
||||||
return reinterpret_cast<int64_t>
|
return reinterpret_cast<int64_t>
|
||||||
(c->machineCode + pad(c->machineCodeSize)
|
(c->machineCode + pad(c->machineCodeSize, TargetBytesPerWord)
|
||||||
+ (key * TargetBytesPerWord));
|
+ (key * TargetBytesPerWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6949,15 +6949,15 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
|
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
|
||||||
intptr_t* target = reinterpret_cast<intptr_t*>
|
target_intptr_t* target = reinterpret_cast<target_intptr_t*>
|
||||||
(c.machineCode + pad(c.machineCodeSize) + i);
|
(c.machineCode + pad(c.machineCodeSize, TargetBytesPerWord) + i);
|
||||||
|
|
||||||
if (n->promise->resolved()) {
|
if (n->promise->resolved()) {
|
||||||
*target = n->promise->value();
|
*target = n->promise->value();
|
||||||
} else {
|
} else {
|
||||||
class Listener: public Promise::Listener {
|
class Listener: public Promise::Listener {
|
||||||
public:
|
public:
|
||||||
Listener(intptr_t* target): target(target){ }
|
Listener(target_intptr_t* target): target(target){ }
|
||||||
|
|
||||||
virtual bool resolve(int64_t value, void** location) {
|
virtual bool resolve(int64_t value, void** location) {
|
||||||
*target = value;
|
*target = value;
|
||||||
@ -6965,7 +6965,7 @@ class MyCompiler: public Compiler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t* target;
|
target_intptr_t* target;
|
||||||
};
|
};
|
||||||
new (n->promise->listen(sizeof(Listener))) Listener(target);
|
new (n->promise->listen(sizeof(Listener))) Listener(target);
|
||||||
}
|
}
|
||||||
|
@ -529,7 +529,7 @@ class Fixie {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned maskSize(unsigned size, bool hasMask) {
|
static unsigned maskSize(unsigned size, bool hasMask) {
|
||||||
return hasMask * ceiling(size, BytesPerWord) * BytesPerWord;
|
return hasMask * ceiling(size, BitsPerWord) * BytesPerWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned totalSize(unsigned size, bool hasMask) {
|
static unsigned totalSize(unsigned size, bool hasMask) {
|
||||||
|
@ -3067,7 +3067,7 @@ class MyProcessor: public Processor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compileMethod(vm::Thread*, Zone*, object*, object*,
|
virtual void compileMethod(vm::Thread*, Zone*, object*, object*,
|
||||||
DelayedPromise**, object)
|
DelayedPromise**, object, OffsetResolver*)
|
||||||
{
|
{
|
||||||
abort(s);
|
abort(s);
|
||||||
}
|
}
|
||||||
@ -3076,6 +3076,10 @@ class MyProcessor: public Processor {
|
|||||||
abort(s);
|
abort(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void normalizeVirtualThunks(vm::Thread*) {
|
||||||
|
abort(s);
|
||||||
|
}
|
||||||
|
|
||||||
virtual unsigned* makeCallTable(vm::Thread*, HeapWalker*) {
|
virtual unsigned* makeCallTable(vm::Thread*, HeapWalker*) {
|
||||||
abort(s);
|
abort(s);
|
||||||
}
|
}
|
||||||
|
@ -122,11 +122,15 @@ class Processor {
|
|||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
compileMethod(Thread* t, Zone* zone, object* constants, object* calls,
|
compileMethod(Thread* t, Zone* zone, object* constants, object* calls,
|
||||||
DelayedPromise** addresses, object method) = 0;
|
DelayedPromise** addresses, object method,
|
||||||
|
OffsetResolver* resolver) = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
visitRoots(Thread* t, HeapWalker* w) = 0;
|
visitRoots(Thread* t, HeapWalker* w) = 0;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
normalizeVirtualThunks(Thread* t) = 0;
|
||||||
|
|
||||||
virtual unsigned*
|
virtual unsigned*
|
||||||
makeCallTable(Thread* t, HeapWalker* w) = 0;
|
makeCallTable(Thread* t, HeapWalker* w) = 0;
|
||||||
|
|
||||||
|
43
src/target.h
43
src/target.h
@ -42,25 +42,62 @@ namespace vm {
|
|||||||
#ifdef TARGET_BYTES_PER_WORD
|
#ifdef TARGET_BYTES_PER_WORD
|
||||||
# if (TARGET_BYTES_PER_WORD == 8)
|
# if (TARGET_BYTES_PER_WORD == 8)
|
||||||
# define TARGET_VW(v) TARGET_V8(v)
|
# define TARGET_VW(v) TARGET_V8(v)
|
||||||
|
|
||||||
typedef uint64_t target_uintptr_t;
|
typedef uint64_t target_uintptr_t;
|
||||||
typedef int64_t target_intptr_t;
|
typedef int64_t target_intptr_t;
|
||||||
|
|
||||||
const unsigned TargetBytesPerWord = 8;
|
const unsigned TargetBytesPerWord = 8;
|
||||||
|
|
||||||
|
const unsigned TargetThreadTailAddress = 2272;
|
||||||
|
const unsigned TargetThreadStackLimit = 2336;
|
||||||
|
const unsigned TargetThreadStack = 2224;
|
||||||
|
const unsigned TargetThreadIp = 2216;
|
||||||
|
const unsigned TargetThreadVirtualCallTarget = 2280;
|
||||||
|
const unsigned TargetThreadVirtualCallIndex = 2288;
|
||||||
|
|
||||||
|
const unsigned TargetClassFixedSize = 12;
|
||||||
|
const unsigned TargetClassArrayElementSize = 14;
|
||||||
|
const unsigned TargetClassVtable = 128;
|
||||||
|
|
||||||
|
const unsigned TargetFieldOffset = 12;
|
||||||
|
|
||||||
# elif (TARGET_BYTES_PER_WORD == 4)
|
# elif (TARGET_BYTES_PER_WORD == 4)
|
||||||
# define TARGET_VW(v) TARGET_V4(v)
|
# define TARGET_VW(v) TARGET_V4(v)
|
||||||
|
|
||||||
typedef uint32_t target_uintptr_t;
|
typedef uint32_t target_uintptr_t;
|
||||||
typedef int32_t target_intptr_t;
|
typedef int32_t target_intptr_t;
|
||||||
|
|
||||||
const unsigned TargetBytesPerWord = 4;
|
const unsigned TargetBytesPerWord = 4;
|
||||||
|
|
||||||
|
const unsigned TargetThreadTailAddress = 2172;
|
||||||
|
const unsigned TargetThreadStackLimit = 2204;
|
||||||
|
const unsigned TargetThreadStack = 2148;
|
||||||
|
const unsigned TargetThreadIp = 2144;
|
||||||
|
const unsigned TargetThreadVirtualCallTarget = 2176;
|
||||||
|
const unsigned TargetThreadVirtualCallIndex = 2180;
|
||||||
|
|
||||||
|
const unsigned TargetClassFixedSize = 8;
|
||||||
|
const unsigned TargetClassArrayElementSize = 10;
|
||||||
|
const unsigned TargetClassVtable = 68;
|
||||||
|
|
||||||
|
const unsigned TargetFieldOffset = 8;
|
||||||
|
|
||||||
# else
|
# else
|
||||||
# error
|
# error
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
typedef uintptr_t target_uintptr_t;
|
# error
|
||||||
typedef intptr_t target_intptr_t;
|
|
||||||
const unsigned TargetBytesPerWord = BytesPerWord;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const unsigned TargetBitsPerWord = TargetBytesPerWord * 8;
|
const unsigned TargetBitsPerWord = TargetBytesPerWord * 8;
|
||||||
|
|
||||||
|
const uintptr_t TargetPointerMask
|
||||||
|
= ((~static_cast<target_uintptr_t>(0)) / TargetBytesPerWord)
|
||||||
|
* TargetBytesPerWord;
|
||||||
|
|
||||||
|
const unsigned TargetArrayLength = TargetBytesPerWord;
|
||||||
|
const unsigned TargetArrayBody = TargetBytesPerWord * 2;
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
||||||
#endif//TARGET_H
|
#endif//TARGET_H
|
||||||
|
@ -2116,6 +2116,9 @@ writeMap(Output* out, Object* type)
|
|||||||
case Object::Scalar: {
|
case Object::Scalar: {
|
||||||
out->write("Type_");
|
out->write("Type_");
|
||||||
out->write(memberTypeEnumName(m));
|
out->write(memberTypeEnumName(m));
|
||||||
|
if (memberNoGC(m)) {
|
||||||
|
out->write("_nogc");
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Object::Array: {
|
case Object::Array: {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
@ -103,6 +104,10 @@ class Vector {
|
|||||||
append(&v, 4);
|
append(&v, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void appendTargetAddress(target_uintptr_t v) {
|
||||||
|
append(&v, TargetBytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
void appendAddress(uintptr_t v) {
|
void appendAddress(uintptr_t v) {
|
||||||
append(&v, BytesPerWord);
|
append(&v, BytesPerWord);
|
||||||
}
|
}
|
||||||
|
12
src/x86.cpp
12
src/x86.cpp
@ -74,13 +74,13 @@ const unsigned StackAlignmentInBytes = 16;
|
|||||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord;
|
const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isInt8(intptr_t v)
|
isInt8(target_intptr_t v)
|
||||||
{
|
{
|
||||||
return v == static_cast<int8_t>(v);
|
return v == static_cast<int8_t>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isInt32(intptr_t v)
|
isInt32(target_intptr_t v)
|
||||||
{
|
{
|
||||||
return v == static_cast<int32_t>(v);
|
return v == static_cast<int32_t>(v);
|
||||||
}
|
}
|
||||||
@ -958,11 +958,11 @@ moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a,
|
|||||||
maybeRex(c, TargetBytesPerWord, b);
|
maybeRex(c, TargetBytesPerWord, b);
|
||||||
opcode(c, 0xb8 + regCode(b));
|
opcode(c, 0xb8 + regCode(b));
|
||||||
if (a->value->resolved()) {
|
if (a->value->resolved()) {
|
||||||
c->code.appendAddress(a->value->value());
|
c->code.appendTargetAddress(a->value->value());
|
||||||
} else {
|
} else {
|
||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, a->value, offset(c), TargetBytesPerWord, promiseOffset);
|
(c, a->value, offset(c), TargetBytesPerWord, promiseOffset);
|
||||||
c->code.appendAddress(static_cast<uintptr_t>(0));
|
c->code.appendTargetAddress(static_cast<target_uintptr_t>(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3446,7 +3446,7 @@ class MyAssembler: public Assembler {
|
|||||||
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
||||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
|
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord),
|
||||||
RegisterOperand,
|
RegisterOperand,
|
||||||
&dst);
|
&dst);
|
||||||
} else {
|
} else {
|
||||||
@ -3455,7 +3455,7 @@ class MyAssembler: public Assembler {
|
|||||||
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
||||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
|
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord),
|
||||||
MemoryOperand,
|
MemoryOperand,
|
||||||
&dst);
|
&dst);
|
||||||
offset += ceiling
|
offset += ceiling
|
||||||
|
Loading…
Reference in New Issue
Block a user