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:
Joel Dice 2011-08-31 21:18:00 -06:00
parent 5d55d61c17
commit e505cbe99d
14 changed files with 779 additions and 328 deletions

View File

@ -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): \

View 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;
}
}

View File

@ -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);
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);
} }

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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;

View File

@ -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

View File

@ -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: {

View File

@ -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);
} }

View File

@ -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