diff --git a/makefile b/makefile index 3474de80f0..852cb6a816 100755 --- a/makefile +++ b/makefile @@ -169,7 +169,8 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions \ "-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \ -D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \ -DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \ - -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" + -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \ + -DTARGET_BYTES_PER_WORD=$(pointer-size) ifneq (,$(filter i386 x86_64,$(arch))) ifeq ($(use-frame-pointer),true) @@ -208,6 +209,12 @@ shared = -shared openjdk-extra-cflags = -fvisibility=hidden +ifeq ($(build-arch),powerpc) + ifneq ($(arch),$(build-arch)) + cflags += -DTARGET_OPPOSITE_ENDIAN + endif +endif + ifeq ($(arch),i386) pointer-size = 4 endif @@ -215,6 +222,10 @@ ifeq ($(arch),powerpc) asm = powerpc pointer-size = 4 + ifneq ($(arch),$(build-arch)) + cflags += -DTARGET_OPPOSITE_ENDIAN + endif + ifneq ($(platform),darwin) ifneq ($(arch),$(build-arch)) converter-cflags += -DOPPOSITE_ENDIAN @@ -251,7 +262,13 @@ ifeq ($(arch),arm) endif endif +ifeq ($(platform),linux) + cflags += -DTARGET_PLATFORM_LINUX +endif + ifeq ($(platform),darwin) + cflags += -DTARGET_PLATFORM_DARWIN + ifeq (${OSX_SDK_SYSROOT},) OSX_SDK_SYSROOT = 10.4u endif @@ -330,6 +347,8 @@ ifeq ($(platform),darwin) endif ifeq ($(platform),windows) + cflags += -DTARGET_PLATFORM_WINDOWS + inc = "$(root)/win32/include" lib = "$(root)/win32/lib" @@ -479,7 +498,8 @@ generated-code = \ $(build)/type-constructors.cpp \ $(build)/type-initializations.cpp \ $(build)/type-java-initializations.cpp \ - $(build)/type-name-initializations.cpp + $(build)/type-name-initializations.cpp \ + $(build)/type-maps.cpp vm-depends := $(generated-code) $(wildcard $(src)/*.h) @@ -537,16 +557,6 @@ bootimage-bin = $(build)/bootimage.bin bootimage-object = $(build)/bootimage-bin.o ifeq ($(bootimage),true) - ifneq ($(build-arch),$(arch)) -$(error "bootimage cross-builds not yet supported") - endif - - ifeq ($(arch),x86_64) - ifneq ($(build-platform),$(platform)) -$(error "bootimage cross-builds not yet supported") - endif - endif - vm-classpath-object = $(bootimage-object) cflags += -DBOOT_IMAGE=\"bootimageBin\" -DAVIAN_CLASSPATH=\"\" else diff --git a/src/assembler.h b/src/assembler.h index 4805f54e80..39d0987ce0 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -343,7 +343,7 @@ class Assembler { virtual void updateCall(UnaryOperation op, void* returnAddress, void* newTarget) = 0; - virtual void setConstant(void* dst, uintptr_t constant) = 0; + virtual void setConstant(void* dst, uint64_t constant) = 0; virtual unsigned alignFrameSize(unsigned sizeInWords) = 0; diff --git a/src/bootimage.cpp b/src/bootimage.cpp index b58439e3a7..0626eb5c77 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -9,11 +9,14 @@ details. */ #include "bootimage.h" +#include "heap.h" #include "heapwalk.h" #include "common.h" #include "machine.h" #include "util.h" +#include "stream.h" #include "assembler.h" +#include "target.h" // since we aren't linking against libstdc++, we must implement this // ourselves: @@ -25,6 +28,95 @@ namespace { const unsigned HeapCapacity = 256 * 1024 * 1024; +const unsigned TargetFixieSizeInBytes = 8 + (TargetBytesPerWord * 2); +const unsigned TargetFixieSizeInWords = ceiling + (TargetFixieSizeInBytes, TargetBytesPerWord); +const unsigned TargetFixieAge = 0; +const unsigned TargetFixieHasMask = 1; +const unsigned TargetFixieSize = 4; + +const bool DebugNativeTarget = false; + +enum Type { + Type_none, + Type_object, + Type_int8_t, + Type_uint8_t, + Type_int16_t, + Type_uint16_t, + Type_int32_t, + Type_uint32_t, + Type_intptr_t, + Type_uintptr_t, + Type_int64_t, + Type_int64_t_pad, + Type_uint64_t, + Type_float, + Type_double, + Type_double_pad, + Type_word, + Type_array +}; + +class Field { + public: + Field(Type type, unsigned offset, unsigned targetOffset): + type(type), offset(offset), targetOffset(targetOffset) + { } + + Type type; + unsigned offset; + unsigned targetOffset; +}; + +class TypeMap { + public: + enum Kind { + NormalKind, + SingletonKind, + PoolKind + }; + + TypeMap(unsigned buildFixedSizeInWords, unsigned targetFixedSizeInWords, + unsigned fixedFieldCount, Kind kind = NormalKind, + unsigned buildArrayElementSizeInBytes = 0, + unsigned targetArrayElementSizeInBytes = 0, + Type arrayElementType = Type_none): + buildFixedSizeInWords(buildFixedSizeInWords), + targetFixedSizeInWords(targetFixedSizeInWords), + fixedFieldCount(fixedFieldCount), + buildArrayElementSizeInBytes(buildArrayElementSizeInBytes), + targetArrayElementSizeInBytes(targetArrayElementSizeInBytes), + arrayElementType(arrayElementType), + kind(kind) + { } + + uintptr_t* targetFixedOffsets() { + return reinterpret_cast(this + 1); + } + + Field* fixedFields() { + return reinterpret_cast + (targetFixedOffsets() + (buildFixedSizeInWords * BytesPerWord)); + } + + static unsigned sizeInBytes(unsigned buildFixedSizeInWords, + unsigned fixedFieldCount) + { + return sizeof(TypeMap) + + (buildFixedSizeInWords * BytesPerWord * BytesPerWord) + + (sizeof(Field) * fixedFieldCount); + } + + unsigned buildFixedSizeInWords; + unsigned targetFixedSizeInWords; + unsigned fixedFieldCount; + unsigned buildArrayElementSizeInBytes; + unsigned targetArrayElementSizeInBytes; + Type arrayElementType; + Kind kind; +}; + // Notes on immutable references in the heap image: // // One of the advantages of a bootimage-based build is that reduces @@ -66,8 +158,10 @@ endsWith(const char* suffix, const char* s, unsigned length) object makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, uintptr_t* codeMap, const char* className, - const char* methodName, const char* methodSpec) + const char* methodName, const char* methodSpec, object typeMaps) { + PROTECT(t, typeMaps); + object constants = 0; PROTECT(t, constants); @@ -76,24 +170,259 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, DelayedPromise* addresses = 0; - for (Finder::Iterator it - (static_cast - (systemClassLoaderFinder(t, root(t, Machine::BootLoader)))); - it.hasMore();) - { + Finder* finder = static_cast + (systemClassLoaderFinder(t, root(t, Machine::BootLoader))); + + 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); + // 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); + System::Region* region = finder->find(name); + + { THREAD_RESOURCE(t, System::Region*, region, region->dispose()); + + class Client: public Stream::Client { + public: + Client(Thread* t): t(t) { } + + virtual void NO_RETURN handleError() { + vm::abort(t); + } + + private: + Thread* t; + } client(t); + + Stream s(&client, region->start(), region->length()); + + uint32_t magic = s.read4(); + expect(t, magic == 0xCAFEBABE); + s.read2(); // minor version + s.read2(); // major version + + unsigned count = s.read2() - 1; + if (count) { + Type types[count + 2]; + types[0] = Type_object; + types[1] = Type_intptr_t; + + for (unsigned i = 2; i < count + 2; ++i) { + switch (s.read1()) { + case CONSTANT_Class: + case CONSTANT_String: + types[i] = Type_object; + s.skip(2); + break; + + case CONSTANT_Integer: + case CONSTANT_Float: + types[i] = Type_int32_t; + s.skip(4); + break; + + case CONSTANT_NameAndType: + case CONSTANT_Fieldref: + case CONSTANT_Methodref: + case CONSTANT_InterfaceMethodref: + types[i] = Type_object; + s.skip(4); + break; + + case CONSTANT_Long: + types[i++] = Type_int64_t; + types[i] = Type_int64_t_pad; + s.skip(8); + break; + + case CONSTANT_Double: + types[i++] = Type_double; + types[i] = Type_double_pad; + s.skip(8); + break; + + case CONSTANT_Utf8: + types[i] = Type_object; + s.skip(s.read2()); + break; + + default: abort(t); + } + } + + object array = makeByteArray + (t, TypeMap::sizeInBytes(count + 2, count + 2)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (count + 2, count + 2, count + 2, TypeMap::PoolKind); + + for (unsigned i = 0; i < count + 2; ++i) { + expect(t, i < map->buildFixedSizeInWords); + + map->targetFixedOffsets()[i * BytesPerWord] + = i * TargetBytesPerWord; + + new (map->fixedFields() + i) Field + (types[i], i * BytesPerWord, i * TargetBytesPerWord); + } + + hashMapInsert + (t, typeMaps, hashMapFind + (t, root(t, Machine::PoolMap), c, objectHash, objectEqual), array, + objectHash); + } + } + + if (classFieldTable(t, c)) { + unsigned count = arrayLength(t, classFieldTable(t, c)); + + Type memberTypes[count + 1]; + memberTypes[0] = Type_object; + unsigned buildMemberOffsets[count + 1]; + buildMemberOffsets[0] = 0; + unsigned targetMemberOffsets[count + 1]; + targetMemberOffsets[0] = 0; + unsigned memberIndex = 1; + unsigned buildMemberOffset = BytesPerWord; + unsigned targetMemberOffset = 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 buildStaticOffset = BytesPerWord * 2; + unsigned targetStaticOffset = TargetBytesPerWord * 2; + + for (unsigned i = 0; i < count; ++i) { + object field = arrayBody(t, classFieldTable(t, c), i); + unsigned size = fieldSize(t, fieldCode(t, field)); + + Type type; + switch (fieldCode(t, field)) { + case ObjectField: + type = Type_object; + size = TargetBytesPerWord; + break; + + case ByteField: + case BooleanField: + type = Type_int8_t; + break; + + case CharField: + case ShortField: + type = Type_int8_t; + break; + + case FloatField: + case IntField: + type = Type_int32_t; + break; + + case LongField: + case DoubleField: + type = Type_int64_t; + break; + + default: abort(t); + } + + if (fieldFlags(t, field) & ACC_STATIC) { + staticTypes[staticIndex] = type; + + while (targetStaticOffset % size) { + ++ targetStaticOffset; + } + + targetStaticOffsets[staticIndex] = targetStaticOffset; + + targetStaticOffset += size; + + buildStaticOffset = fieldOffset(t, field); + buildStaticOffsets[staticIndex] = buildStaticOffset; + + ++ staticIndex; + } else { + memberTypes[memberIndex] = type; + + while (targetMemberOffset % size) { + ++ targetMemberOffset; + } + + targetMemberOffsets[memberIndex] = targetMemberOffset; + + targetMemberOffset += size; + + buildMemberOffset = fieldOffset(t, field); + buildMemberOffsets[memberIndex] = buildMemberOffset; + + ++ memberIndex; + } + } + + { object array = makeByteArray + (t, TypeMap::sizeInBytes + (ceiling(classFixedSize(t, c), BytesPerWord), memberIndex)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (ceiling(classFixedSize(t, c), BytesPerWord), + ceiling(targetMemberOffset, TargetBytesPerWord), memberIndex); + + for (unsigned i = 0; i < memberIndex; ++i) { + expect(t, buildMemberOffsets[i] + < map->buildFixedSizeInWords * BytesPerWord); + + map->targetFixedOffsets()[buildMemberOffsets[i]] + = targetMemberOffsets[i]; + + new (map->fixedFields() + i) Field + (memberTypes[i], buildMemberOffsets[i], targetMemberOffsets[i]); + } + + hashMapInsert(t, typeMaps, c, array, objectHash); + } + + if (classStaticTable(t, c)) { + object array = makeByteArray + (t, TypeMap::sizeInBytes + (singletonCount(t, classStaticTable(t, c)) + 2, staticIndex)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (singletonCount(t, classStaticTable(t, c)) + 2, + ceiling(targetStaticOffset, TargetBytesPerWord), staticIndex, + TypeMap::SingletonKind); + + for (unsigned i = 0; i < staticIndex; ++i) { + expect(t, buildStaticOffsets[i] + < map->buildFixedSizeInWords * BytesPerWord); + + map->targetFixedOffsets()[buildStaticOffsets[i]] + = targetStaticOffsets[i]; + + new (map->fixedFields() + i) Field + (staticTypes[i], buildStaticOffsets[i], targetStaticOffsets[i]); + } + + hashMapInsert + (t, typeMaps, classStaticTable(t, c), array, objectHash); + } + } + if (classMethodTable(t, c)) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { object method = arrayBody(t, classMethodTable(t, c), i); @@ -163,18 +492,18 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, for (; addresses; addresses = addresses->next) { uint8_t* value = reinterpret_cast(addresses->basis->value()); - assert(t, value >= code); + expect(t, value >= code); void* location; bool flat = addresses->listener->resolve (reinterpret_cast(code), &location); - uintptr_t offset = value - code; + target_uintptr_t offset = value - code; if (flat) { offset |= BootFlatConstant; } - memcpy(location, &offset, BytesPerWord); + memcpy(location, &offset, TargetBytesPerWord); - assert(t, reinterpret_cast(location) + expect(t, reinterpret_cast(location) >= reinterpret_cast(code)); markBit(codeMap, reinterpret_cast(location) @@ -187,8 +516,6 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, unsigned objectSize(Thread* t, object o) { - assert(t, not objectExtended(t, o)); - return baseSize(t, o, objectClass(t, o)); } @@ -214,20 +541,310 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants) } } +TypeMap* +typeMap(Thread* t, object typeMaps, object p) +{ + return reinterpret_cast + (&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 +targetOffset(Thread* t, object typeMaps, object p, unsigned offset) +{ + TypeMap* map = typeMap(t, typeMaps, p); + + if (map->targetArrayElementSizeInBytes + and offset >= map->buildFixedSizeInWords * BytesPerWord) + { + return (map->targetFixedSizeInWords * TargetBytesPerWord) + + (((offset - (map->buildFixedSizeInWords * BytesPerWord)) + / map->buildArrayElementSizeInBytes) + * map->targetArrayElementSizeInBytes); + } else { + return map->targetFixedOffsets()[offset]; + } +} + +unsigned +targetSize(Thread* t, object typeMaps, object p) +{ + TypeMap* map = typeMap(t, typeMaps, p); + + if (map->targetArrayElementSizeInBytes) { + return map->targetFixedSizeInWords + + ceiling(map->targetArrayElementSizeInBytes + * cast + (p, (map->buildFixedSizeInWords - 1) * BytesPerWord), + TargetBytesPerWord); + } else { + switch (map->kind) { + case TypeMap::NormalKind: + return map->targetFixedSizeInWords; + + case TypeMap::SingletonKind: + return map->targetFixedSizeInWords + singletonMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord); + + case TypeMap::PoolKind: { + unsigned maskSize = poolMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord); + + return map->targetFixedSizeInWords + maskSize + singletonMaskSize + (map->targetFixedSizeInWords - 2 + maskSize, TargetBitsPerWord); + } + + default: abort(t); + } + } +} + +void +copy(Thread* t, uint8_t* src, uint8_t* dst, Type type) +{ + switch (type) { + case Type_int8_t: + memcpy(dst, src, 1); + break; + + case Type_int16_t: { + int16_t s; memcpy(&s, src, 2); + int16_t d = TARGET_V2(s); + memcpy(dst, &d, 2); + } break; + + case Type_int32_t: + case Type_float: { + int32_t s; memcpy(&s, src, 4); + int32_t d = TARGET_V4(s); + memcpy(dst, &d, 4); + } break; + + case Type_int64_t: + case Type_double: { + int64_t s; memcpy(&s, src, 8); + int64_t d = TARGET_V8(s); + memcpy(dst, &d, 8); + } break; + + case Type_int64_t_pad: + case Type_double_pad: + break; + + case Type_intptr_t: { + intptr_t s; memcpy(&s, src, BytesPerWord); + target_intptr_t d = TARGET_VW(s); + memcpy(dst, &d, TargetBytesPerWord); + } break; + + case Type_object: { + memset(dst, 0, TargetBytesPerWord); + } break; + + default: abort(t); + } +} + +bool +nonObjectsEqual(uint8_t* src, uint8_t* dst, Type type) +{ + switch (type) { + case Type_int8_t: + return memcmp(dst, src, 1) == 0; + + case Type_int16_t: + return memcmp(dst, src, 2) == 0; + + case Type_int32_t: + case Type_float: + return memcmp(dst, src, 4) == 0; + + case Type_int64_t: + case Type_double: + return memcmp(dst, src, 8) == 0; + + case Type_int64_t_pad: + case Type_double_pad: + return true; + + case Type_intptr_t: + return memcmp(dst, src, BytesPerWord) == 0; + + case Type_object: + return true; + + default: abort(); + } +} + +bool +nonObjectsEqual(TypeMap* map, uint8_t* src, uint8_t* dst) +{ + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + if (not nonObjectsEqual + (src + field->offset, dst + field->targetOffset, field->type)) + { + return false; + } + } + + if (map->targetArrayElementSizeInBytes) { + unsigned fixedSize = map->buildFixedSizeInWords * BytesPerWord; + unsigned count = cast(src, fixedSize - BytesPerWord); + + for (unsigned i = 0; i < count; ++i) { + if (not nonObjectsEqual + (src + fixedSize + (i * map->buildArrayElementSizeInBytes), + dst + (map->targetFixedSizeInWords * TargetBytesPerWord) + + (i * map->targetArrayElementSizeInBytes), map->arrayElementType)) + { + return false; + } + } + } + + return true; +} + +void +copy(Thread* t, object typeMaps, object p, uint8_t* dst) +{ + TypeMap* map = typeMap(t, typeMaps, p); + + uint8_t* src = reinterpret_cast(p); + + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + if (field->type > Type_array) abort(t); + copy(t, src + field->offset, dst + field->targetOffset, field->type); + } + + if (map->targetArrayElementSizeInBytes) { + unsigned fixedSize = map->buildFixedSizeInWords * BytesPerWord; + unsigned count = cast(p, fixedSize - BytesPerWord); + + for (unsigned i = 0; i < count; ++i) { + copy(t, src + fixedSize + (i * map->buildArrayElementSizeInBytes), + dst + (map->targetFixedSizeInWords * TargetBytesPerWord) + + (i * map->targetArrayElementSizeInBytes), map->arrayElementType); + } + } else { + switch (map->kind) { + case TypeMap::NormalKind: + break; + + case TypeMap::SingletonKind: { + uint8_t* mask = dst + (map->targetFixedSizeInWords * TargetBytesPerWord); + memset(mask, 0, singletonMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord) + * TargetBytesPerWord); + + 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(mask)[offset / 32] + |= static_cast(1) << (offset % 32); + } + } + + if (DebugNativeTarget) { + expect + (t, memcmp + (src + (map->targetFixedSizeInWords * TargetBytesPerWord), mask, + singletonMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord) + * TargetBytesPerWord) == 0); + } + } break; + + case TypeMap::PoolKind: { + unsigned poolMaskSize = vm::poolMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord); + + uint8_t* poolMask = dst + + (map->targetFixedSizeInWords * TargetBytesPerWord); + + memset(poolMask, 0, poolMaskSize * TargetBytesPerWord); + + uint8_t* objectMask = dst + + ((map->targetFixedSizeInWords + poolMaskSize) * TargetBytesPerWord); + + memset(objectMask, 0, singletonMaskSize + (map->targetFixedSizeInWords - 2 + poolMaskSize, + TargetBitsPerWord) * TargetBytesPerWord); + + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + switch (field->type) { + case Type_object: + reinterpret_cast(objectMask)[i / 32] + |= static_cast(1) << (i % 32); + break; + + case Type_float: + case Type_double: + reinterpret_cast(poolMask) + [i / TargetBitsPerWord] + |= static_cast(1) << (i % TargetBitsPerWord); + break; + + default: + break; + } + } + + if (DebugNativeTarget) { + expect + (t, memcmp + (src + (map->targetFixedSizeInWords * TargetBytesPerWord), poolMask, + (poolMaskSize + singletonMaskSize + (map->targetFixedSizeInWords - 2 + poolMaskSize, + TargetBitsPerWord)) + * TargetBytesPerWord) == 0); + } + } break; + + default: abort(t); + } + } + + if (DebugNativeTarget) { + expect(t, targetSize(t, typeMaps, p) == baseSize(t, p, objectClass(t, p))); + expect(t, nonObjectsEqual(map, src, dst)); + } +} + HeapWalker* makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, - unsigned capacity, object constants) + unsigned capacity, object constants, object typeMaps) { class Visitor: public HeapVisitor { public: - Visitor(Thread* t, uintptr_t* heap, uintptr_t* map, unsigned capacity): - t(t), currentObject(0), currentNumber(0), currentOffset(0), heap(heap), - map(map), position(0), capacity(capacity) + Visitor(Thread* t, object typeMaps, uintptr_t* heap, + uintptr_t* map, unsigned capacity): + t(t), typeMaps(typeMaps), currentObject(0), currentNumber(0), + currentOffset(0), heap(heap), map(map), position(0), capacity(capacity) { } void visit(unsigned number) { if (currentObject) { - unsigned offset = currentNumber - 1 + currentOffset; + if (DebugNativeTarget) { + expect + (t, targetOffset + (t, typeMaps, currentObject, currentOffset * BytesPerWord) + == currentOffset * BytesPerWord); + } + + unsigned offset = currentNumber - 1 + + (targetOffset + (t, typeMaps, currentObject, currentOffset * BytesPerWord) + / TargetBytesPerWord); + unsigned mark = heap[offset] & (~PointerMask); unsigned value = number | (mark << BootShift); @@ -243,10 +860,11 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, virtual unsigned visitNew(object p) { if (p) { - unsigned size = objectSize(t, p); + unsigned size = targetSize(t, typeMaps, p); unsigned number; if ((currentObject + and objectClass(t, currentObject) == type(t, Machine::ClassType) and (currentOffset * BytesPerWord) == ClassStaticTable) or instanceOf(t, type(t, Machine::SystemClassLoaderType), p)) { @@ -257,24 +875,41 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, // to runtime-allocated memory would fail because we don't // scan non-fixed objects in the heap image during GC. - FixedAllocator allocator - (t->m->system, reinterpret_cast(heap + position), - (capacity - position) * BytesPerWord); + target_uintptr_t* dst = heap + position + TargetFixieSizeInWords; - unsigned totalInBytes; - uintptr_t* dst = static_cast - (t->m->heap->allocateImmortalFixed - (&allocator, size, true, &totalInBytes)); + unsigned maskSize = ceiling(size, TargetBytesPerWord); - memcpy(dst, p, size * BytesPerWord); + unsigned total = TargetFixieSizeInWords + size + maskSize; + + expect(t, position + total < capacity); + + memset(heap + position, 0, TargetFixieSizeInBytes); + + uint8_t age = FixieTenureThreshold + 1; + memcpy(reinterpret_cast(heap + position) + + TargetFixieAge, &age, 1); + + uint8_t hasMask = true; + memcpy(reinterpret_cast(heap + position) + + TargetFixieHasMask, &hasMask, 1); + + uint32_t targetSize = TARGET_V4(size); + memcpy(reinterpret_cast(heap + position) + + TargetFixieSize, &targetSize, 4); + + copy(t, typeMaps, p, reinterpret_cast(dst)); dst[0] |= FixedMark; + memset(heap + position + TargetFixieSizeInWords + size, 0, + maskSize * TargetBytesPerWord); + number = (dst - heap) + 1; - position += ceiling(totalInBytes, BytesPerWord); + position += total; } else { - assert(t, position + size < capacity); - memcpy(heap + position, p, size * BytesPerWord); + expect(t, position + size < capacity); + + copy(t, typeMaps, p, reinterpret_cast(heap + position)); number = position + 1; position += size; @@ -303,14 +938,15 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, } Thread* t; + object typeMaps; object currentObject; unsigned currentNumber; unsigned currentOffset; - uintptr_t* heap; - uintptr_t* map; + target_uintptr_t* heap; + target_uintptr_t* map; unsigned position; unsigned capacity; - } visitor(t, heap, map, capacity / BytesPerWord); + } visitor(t, typeMaps, heap, map, capacity / TargetBytesPerWord); HeapWalker* w = makeHeapWalker(t, &visitor); visitRoots(t, image, w, constants); @@ -326,7 +962,7 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap, { for (; constants; constants = tripleThird(t, constants)) { unsigned target = heapTable->find(tripleFirst(t, constants)); - assert(t, target > 0); + expect(t, target > 0); for (Promise::Listener* pl = static_cast (pointerValue(t, tripleSecond(t, constants)))->listener; @@ -334,13 +970,13 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap, { void* location; bool flat = pl->resolve(0, &location); - uintptr_t offset = target | BootHeapOffset; + target_uintptr_t offset = target | BootHeapOffset; if (flat) { offset |= BootFlatConstant; } - memcpy(location, &offset, BytesPerWord); + memcpy(location, &offset, TargetBytesPerWord); - assert(t, reinterpret_cast(location) + expect(t, reinterpret_cast(location) >= reinterpret_cast(code)); markBit(codeMap, reinterpret_cast(location) @@ -366,74 +1002,221 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code, (t->m->heap->allocate(codeMapSize(codeCapacity))); memset(codeMap, 0, codeMapSize(codeCapacity)); - object constants = makeCodeImage - (t, &zone, image, code, codeMap, className, methodName, methodSpec); + object classPoolMap; + object typeMaps; + object constants; - PROTECT(t, constants); + { classPoolMap = makeHashMap(t, 0, 0); + PROTECT(t, classPoolMap); - // this map will not be used when the bootimage is loaded, so - // there's no need to preserve it: - setRoot(t, Machine::ByteArrayMap, makeWeakHashMap(t, 0, 0)); + setRoot(t, Machine::PoolMap, classPoolMap); - // name all primitive classes so we don't try to update immutable - // references at runtime: - { object name = makeByteArray(t, "void"); - set(t, type(t, Machine::JvoidType), ClassName, name); + typeMaps = makeHashMap(t, 0, 0); + PROTECT(t, typeMaps); + + constants = makeCodeImage + (t, &zone, image, code, codeMap, className, methodName, methodSpec, + typeMaps); + + PROTECT(t, constants); + +#include "type-maps.cpp" + + for (unsigned i = 0; i < arrayLength(t, t->m->types); ++i) { + Type* source = types[i]; + unsigned count = 0; + while (source[count] != Type_none) { + ++ count; + } + ++ count; + + Type types[count]; + types[0] = Type_object; + unsigned buildOffsets[count]; + buildOffsets[0] = 0; + unsigned buildOffset = BytesPerWord; + unsigned targetOffsets[count]; + targetOffsets[0] = 0; + unsigned targetOffset = TargetBytesPerWord; + bool sawArray = false; + unsigned buildSize = BytesPerWord; + unsigned targetSize = TargetBytesPerWord; + for (unsigned j = 1; j < count; ++j) { + switch (source[j - 1]) { + case Type_object: + types[j] = Type_object; + buildSize = BytesPerWord; + targetSize = TargetBytesPerWord; + break; + + case Type_word: + case Type_intptr_t: + case Type_uintptr_t: + types[j] = Type_intptr_t; + buildSize = BytesPerWord; + targetSize = TargetBytesPerWord; + break; + + case Type_int8_t: + case Type_uint8_t: + types[j] = Type_int8_t; + buildSize = targetSize = 1; + break; + + case Type_int16_t: + case Type_uint16_t: + types[j] = Type_int16_t; + buildSize = targetSize = 2; + break; + + case Type_int32_t: + case Type_uint32_t: + case Type_float: + types[j] = Type_int32_t; + buildSize = targetSize = 4; + break; + + case Type_int64_t: + case Type_uint64_t: + case Type_double: + types[j] = Type_int64_t; + buildSize = targetSize = 8; + break; + + case Type_array: + types[j] = Type_none; + buildSize = targetSize = 0; + break; + + default: abort(t); + } + + if (source[j - 1] == Type_array) { + sawArray = true; + } + + if (not sawArray) { + while (buildOffset % buildSize) { + ++ buildOffset; + } + + buildOffsets[j] = buildOffset; + + buildOffset += buildSize; + + while (targetOffset % targetSize) { + ++ targetOffset; + } + + targetOffsets[j] = targetOffset; + + targetOffset += targetSize; + } + } + + unsigned fixedFieldCount; + Type arrayElementType; + unsigned buildArrayElementSize; + unsigned targetArrayElementSize; + if (sawArray) { + fixedFieldCount = count - 2; + arrayElementType = types[count - 1]; + buildArrayElementSize = buildSize; + targetArrayElementSize = targetSize; + } else { + fixedFieldCount = count; + arrayElementType = Type_none; + buildArrayElementSize = 0; + targetArrayElementSize = 0; + } + + object array = makeByteArray + (t, TypeMap::sizeInBytes + (ceiling(buildOffset, BytesPerWord), fixedFieldCount)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (ceiling(buildOffset, BytesPerWord), + ceiling(targetOffset, TargetBytesPerWord), + fixedFieldCount, TypeMap::NormalKind, buildArrayElementSize, + targetArrayElementSize, arrayElementType); + + for (unsigned j = 0; j < fixedFieldCount; ++j) { + expect(t, buildOffsets[j] < map->buildFixedSizeInWords * BytesPerWord); + + map->targetFixedOffsets()[buildOffsets[j]] = targetOffsets[j]; + + new (map->fixedFields() + j) Field + (types[j], buildOffsets[j], targetOffsets[j]); + } + + hashMapInsertOrReplace + (t, typeMaps, type(t, static_cast(i)), array, + objectHash, objectEqual); + } + + // these roots will not be used when the bootimage is loaded, so + // there's no need to preserve them: + setRoot(t, Machine::PoolMap, 0); + setRoot(t, Machine::ByteArrayMap, makeWeakHashMap(t, 0, 0)); + + // name all primitive classes so we don't try to update immutable + // references at runtime: + { object name = makeByteArray(t, "void"); + set(t, type(t, Machine::JvoidType), ClassName, name); - name = makeByteArray(t, "boolean"); - set(t, type(t, Machine::JbooleanType), ClassName, name); + name = makeByteArray(t, "boolean"); + set(t, type(t, Machine::JbooleanType), ClassName, name); - name = makeByteArray(t, "byte"); - set(t, type(t, Machine::JbyteType), ClassName, name); + name = makeByteArray(t, "byte"); + set(t, type(t, Machine::JbyteType), ClassName, name); - name = makeByteArray(t, "short"); - set(t, type(t, Machine::JshortType), ClassName, name); + name = makeByteArray(t, "short"); + set(t, type(t, Machine::JshortType), ClassName, name); - name = makeByteArray(t, "char"); - set(t, type(t, Machine::JcharType), ClassName, name); + name = makeByteArray(t, "char"); + set(t, type(t, Machine::JcharType), ClassName, name); - name = makeByteArray(t, "int"); - set(t, type(t, Machine::JintType), ClassName, name); + name = makeByteArray(t, "int"); + set(t, type(t, Machine::JintType), ClassName, name); - name = makeByteArray(t, "float"); - set(t, type(t, Machine::JfloatType), ClassName, name); + name = makeByteArray(t, "float"); + set(t, type(t, Machine::JfloatType), ClassName, name); - name = makeByteArray(t, "long"); - set(t, type(t, Machine::JlongType), ClassName, name); + name = makeByteArray(t, "long"); + set(t, type(t, Machine::JlongType), ClassName, name); - name = makeByteArray(t, "double"); - set(t, type(t, Machine::JdoubleType), ClassName, name); + name = makeByteArray(t, "double"); + set(t, type(t, Machine::JdoubleType), ClassName, name); + } + + // resolve primitive array classes in case they are needed at + // runtime: + { object name = makeByteArray(t, "[B"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[Z"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[S"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[C"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[I"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[J"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[F"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[D"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + } } - // resolve primitive array classes in case they are needed at - // runtime: - { object name = makeByteArray(t, "[B"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[Z"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[S"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[C"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[I"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[J"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[F"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[D"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - } - - collect(t, Heap::MajorCollection); - uintptr_t* heap = static_cast (t->m->heap->allocate(HeapCapacity)); uintptr_t* heapMap = static_cast @@ -441,7 +1224,7 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code, memset(heapMap, 0, heapMapSize(HeapCapacity)); HeapWalker* heapWalker = makeHeapImage - (t, image, heap, heapMap, HeapCapacity, constants); + (t, image, heap, heapMap, HeapCapacity, constants, typeMaps); updateConstants(t, constants, code, codeMap, heapWalker->map()); @@ -512,7 +1295,7 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code, + (image->stringCount * sizeof(unsigned)) + (image->callCount * sizeof(unsigned) * 2); - while (offset % BytesPerWord) { + while (offset % TargetBytesPerWord) { uint8_t c = 0; fwrite(&c, 1, 1, out); ++ offset; diff --git a/src/compile.cpp b/src/compile.cpp index afd590fc8f..fa1ffa4778 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -13,6 +13,7 @@ #include "vector.h" #include "process.h" #include "assembler.h" +#include "target.h" #include "compiler.h" #include "arch.h" @@ -52,7 +53,7 @@ const bool Continuations = true; const bool Continuations = false; #endif -const unsigned MaxNativeCallFootprint = BytesPerWord == 8 ? 4 : 5; +const unsigned MaxNativeCallFootprint = TargetBytesPerWord == 8 ? 4 : 5; const unsigned InitialZoneCapacityInBytes = 64 * 1024; @@ -3164,7 +3165,7 @@ resultSize(MyThread* t, unsigned code) return 4; case ObjectField: - return BytesPerWord; + return TargetBytesPerWord; case LongField: case DoubleField: @@ -3305,8 +3306,8 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, methodParameterFootprint(t, target)); c->store - (BytesPerWord, frame->addressOperand(returnAddressPromise), - BytesPerWord, c->memory + (TargetBytesPerWord, frame->addressOperand(returnAddressPromise), + TargetBytesPerWord, c->memory (c->register_(t->arch->thread()), Compiler::AddressType, difference(&(t->tailAddress), t))); @@ -3455,7 +3456,7 @@ compileDirectReferenceInvoke(MyThread* t, Frame* frame, Thunk thunk, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 2, c->register_(t->arch->thread()), frame->append(pair)), reference, isStatic, tailCall); @@ -3497,7 +3498,7 @@ compileDirectAbstractInvoke(MyThread* t, Frame* frame, Thunk thunk, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 2, c->register_(t->arch->thread()), frame->append(target)), target, tailCall); @@ -3560,7 +3561,7 @@ inTryBlock(MyThread* t, object code, unsigned ip) if (table) { unsigned length = exceptionHandlerTableLength(t, table); for (unsigned i = 0; i < length; ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, table, i); + uint64_t eh = exceptionHandlerTableBody(t, table, i); if (ip >= exceptionHandlerStart(eh) and ip < exceptionHandlerEnd(eh)) { @@ -3867,16 +3868,18 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case aaload: frame->pushObject (c->load - (BytesPerWord, BytesPerWord, c->memory - (array, Compiler::ObjectType, ArrayBody, index, BytesPerWord), - BytesPerWord)); + (TargetBytesPerWord, TargetBytesPerWord, c->memory + (array, Compiler::ObjectType, ArrayBody, index, + TargetBytesPerWord), + TargetBytesPerWord)); break; case faload: frame->pushInt (c->load (4, 4, c->memory - (array, Compiler::FloatType, ArrayBody, index, 4), BytesPerWord)); + (array, Compiler::FloatType, ArrayBody, index, 4), + TargetBytesPerWord)); break; case iaload: @@ -3884,7 +3887,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (4, 4, c->memory (array, Compiler::IntegerType, ArrayBody, index, 4), - BytesPerWord)); + TargetBytesPerWord)); break; case baload: @@ -3892,7 +3895,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (1, 1, c->memory (array, Compiler::IntegerType, ArrayBody, index, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case caload: @@ -3900,7 +3903,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->loadz (2, 2, c->memory (array, Compiler::IntegerType, ArrayBody, index, 2), - BytesPerWord)); + TargetBytesPerWord)); break; case daload: @@ -3922,7 +3925,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (2, 2, c->memory (array, Compiler::IntegerType, ArrayBody, index, 2), - BytesPerWord)); + TargetBytesPerWord)); break; } } break; @@ -3968,32 +3971,33 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->add (4, c->constant(ArrayBody, Compiler::IntegerType), c->shl - (4, c->constant(log(BytesPerWord), Compiler::IntegerType), index)), + (4, c->constant(log(TargetBytesPerWord), Compiler::IntegerType), + index)), value); } break; case fastore: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (array, Compiler::FloatType, ArrayBody, index, 4)); break; case iastore: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (array, Compiler::IntegerType, ArrayBody, index, 4)); break; case bastore: c->store - (BytesPerWord, value, 1, c->memory + (TargetBytesPerWord, value, 1, c->memory (array, Compiler::IntegerType, ArrayBody, index, 1)); break; case castore: case sastore: c->store - (BytesPerWord, value, 2, c->memory + (TargetBytesPerWord, value, 2, c->memory (array, Compiler::IntegerType, ArrayBody, index, 2)); break; @@ -4062,7 +4066,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 3, c->register_(t->arch->thread()), frame->append(argument), length)); @@ -4070,16 +4074,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case areturn: { handleExit(t, frame); - c->return_(BytesPerWord, frame->popObject()); + c->return_(TargetBytesPerWord, frame->popObject()); } return; case arraylength: { frame->pushInt (c->load - (BytesPerWord, BytesPerWord, + (TargetBytesPerWord, TargetBytesPerWord, c->memory (frame->popObject(), Compiler::IntegerType, ArrayLength, 0, 1), - BytesPerWord)); + TargetBytesPerWord)); } break; case astore: @@ -4367,7 +4371,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, if (LIKELY(field)) { if ((fieldFlags(t, field) & ACC_VOLATILE) - and BytesPerWord == 4 + and TargetBytesPerWord == 4 and (fieldCode(t, field) == DoubleField or fieldCode(t, field) == LongField)) { @@ -4375,7 +4379,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->call (c->constant - (getThunk(t, acquireMonitorForObjectThunk), Compiler::AddressType), + (getThunk(t, acquireMonitorForObjectThunk), + Compiler::AddressType), 0, frame->trace(0, 0), 0, Compiler::VoidType, 2, c->register_(t->arch->thread()), frame->append(field)); @@ -4421,7 +4426,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (1, 1, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case CharField: @@ -4429,7 +4434,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->loadz (2, 2, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case ShortField: @@ -4437,7 +4442,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (2, 2, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case FloatField: @@ -4445,7 +4450,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (4, 4, c->memory (table, Compiler::FloatType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case IntField: @@ -4453,7 +4458,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (4, 4, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case DoubleField: @@ -4473,10 +4478,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case ObjectField: frame->pushObject (c->load - (BytesPerWord, BytesPerWord, + (TargetBytesPerWord, TargetBytesPerWord, c->memory (table, Compiler::ObjectType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; default: @@ -4484,7 +4489,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } if (fieldFlags(t, field) & ACC_VOLATILE) { - if (BytesPerWord == 4 + if (TargetBytesPerWord == 4 and (fieldCode(t, field) == DoubleField or fieldCode(t, field) == LongField)) { @@ -4551,11 +4556,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case i2b: { - frame->pushInt(c->load(BytesPerWord, 1, frame->popInt(), BytesPerWord)); + frame->pushInt + (c->load(TargetBytesPerWord, 1, frame->popInt(), TargetBytesPerWord)); } break; case i2c: { - frame->pushInt(c->loadz(BytesPerWord, 2, frame->popInt(), BytesPerWord)); + frame->pushInt + (c->loadz(TargetBytesPerWord, 2, frame->popInt(), TargetBytesPerWord)); } break; case i2d: { @@ -4567,11 +4574,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case i2l: - frame->pushLong(c->load(BytesPerWord, 4, frame->popInt(), 8)); + frame->pushLong(c->load(TargetBytesPerWord, 4, frame->popInt(), 8)); break; case i2s: { - frame->pushInt(c->load(BytesPerWord, 2, frame->popInt(), BytesPerWord)); + frame->pushInt + (c->load(TargetBytesPerWord, 2, frame->popInt(), TargetBytesPerWord)); } break; case iadd: { @@ -4637,9 +4645,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* target = frame->machineIp(newIp); if (instruction == if_acmpeq) { - c->jumpIfEqual(BytesPerWord, a, b, target); + c->jumpIfEqual(TargetBytesPerWord, a, b, target); } else { - c->jumpIfNotEqual(BytesPerWord, a, b, target); + c->jumpIfNotEqual(TargetBytesPerWord, a, b, target); } saveStateAndCompile(t, frame, newIp); @@ -4737,9 +4745,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* target = frame->machineIp(newIp); if (instruction == ifnull) { - c->jumpIfEqual(BytesPerWord, a, b, target); + c->jumpIfEqual(TargetBytesPerWord, a, b, target); } else { - c->jumpIfNotEqual(BytesPerWord, a, b, target); + c->jumpIfNotEqual(TargetBytesPerWord, a, b, target); } saveStateAndCompile(t, frame, newIp); @@ -4868,7 +4876,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 3, c->register_(t->arch->thread()), frame->append(argument), c->peek(1, parameterFootprint - 1)), @@ -4976,7 +4984,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* result = c->stackCall (c->memory (c->and_ - (BytesPerWord, c->constant(PointerMask, Compiler::IntegerType), + (TargetBytesPerWord, c->constant + (PointerMask, Compiler::IntegerType), c->memory(instance, Compiler::ObjectType, 0, 0, 1)), Compiler::ObjectType, offset, 0, 1), tailCall ? Compiler::TailJump : 0, @@ -5008,7 +5017,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 3, c->register_(t->arch->thread()), frame->append(pair), c->peek(1, methodReferenceParameterFootprint @@ -5132,7 +5141,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case l2i: - frame->pushInt(c->load(8, 8, frame->popLong(), BytesPerWord)); + frame->pushInt(c->load(8, 8, frame->popLong(), TargetBytesPerWord)); break; case ladd: { @@ -5201,7 +5210,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 2, c->register_(t->arch->thread()), frame->append(makePair(t, context->method, reference)))); @@ -5216,7 +5225,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (getThunk(t, getJClass64Thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 2, c->register_(t->arch->thread()), frame->append(v))); } else { @@ -5330,7 +5339,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->call (c->constant (getThunk(t, lookUpAddressThunk), Compiler::AddressType), - 0, 0, BytesPerWord, Compiler::AddressType, + 0, 0, TargetBytesPerWord, Compiler::AddressType, 4, key, start, c->constant(pairCount, Compiler::IntegerType), default_)); @@ -5477,7 +5486,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 4, c->register_(t->arch->thread()), frame->append(argument), c->constant(dimensions, Compiler::IntegerType), @@ -5516,7 +5525,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 2, c->register_(t->arch->thread()), frame->append(argument))); } break; @@ -5531,7 +5540,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, makeBlankArrayThunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 3, c->register_(t->arch->thread()), c->constant(type, Compiler::IntegerType), length)); @@ -5593,7 +5602,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } if (fieldFlags(t, field) & ACC_VOLATILE) { - if (BytesPerWord == 4 + if (TargetBytesPerWord == 4 and (fieldCode == DoubleField or fieldCode == LongField)) { PROTECT(t, field); @@ -5625,26 +5634,26 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case ByteField: case BooleanField: c->store - (BytesPerWord, value, 1, c->memory + (TargetBytesPerWord, value, 1, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1)); break; case CharField: case ShortField: c->store - (BytesPerWord, value, 2, c->memory + (TargetBytesPerWord, value, 2, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1)); break; case FloatField: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (table, Compiler::FloatType, fieldOffset(t, field), 0, 1)); break; case IntField: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1)); break; @@ -5686,7 +5695,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } if (fieldFlags(t, field) & ACC_VOLATILE) { - if (BytesPerWord == 4 + if (TargetBytesPerWord == 4 and (fieldCode == DoubleField or fieldCode == LongField)) { c->call @@ -5862,9 +5871,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->jmp (c->load - (BytesPerWord, BytesPerWord, c->memory - (start, Compiler::AddressType, 0, normalizedKey, BytesPerWord), - BytesPerWord)); + (TargetBytesPerWord, TargetBytesPerWord, c->memory + (start, Compiler::AddressType, 0, normalizedKey, TargetBytesPerWord), + TargetBytesPerWord)); Compiler::State* state = c->saveState(); @@ -6018,9 +6027,9 @@ truncateLineNumberTable(Thread* t, object table, unsigned length) PROTECT(t, table); object newTable = makeLineNumberTable(t, length); - memcpy(lineNumberTableBody(t, newTable, 0), - lineNumberTableBody(t, table, 0), - length * sizeof(LineNumber)); + memcpy(&lineNumberTableBody(t, newTable, 0), + &lineNumberTableBody(t, table, 0), + length * sizeof(uint64_t)); return newTable; } @@ -6046,7 +6055,7 @@ translateExceptionHandlerTable(MyThread* t, Context* context, intptr_t start) unsigned ni = 0; for (unsigned oi = 0; oi < length; ++ oi) { - ExceptionHandler* oldHandler = exceptionHandlerTableBody + uint64_t oldHandler = exceptionHandlerTableBody (t, oldTable, oi); int handlerStart = resolveIpForwards @@ -6107,8 +6116,7 @@ translateLineNumberTable(MyThread* t, Context* context, intptr_t start) object newTable = makeLineNumberTable(t, length); unsigned ni = 0; for (unsigned oi = 0; oi < length; ++oi) { - LineNumber* oldLine = lineNumberTableBody(t, oldTable, oi); - LineNumber* newLine = lineNumberTableBody(t, newTable, ni); + uint64_t oldLine = lineNumberTableBody(t, oldTable, oi); int ip = resolveIpForwards (context, lineNumberIp(oldLine), oi + 1 < length @@ -6116,12 +6124,9 @@ translateLineNumberTable(MyThread* t, Context* context, intptr_t start) : lineNumberIp(oldLine) + 1); if (LIKELY(ip >= 0)) { - lineNumberIp(newLine) - = context->compiler->machineIp(ip)->value() - start; - - lineNumberLine(newLine) = lineNumberLine(oldLine); - - ++ ni; + lineNumberTableBody(t, newTable, ni++) = lineNumber + (context->compiler->machineIp(ip)->value() - start, + lineNumberLine(oldLine)); } } @@ -6675,7 +6680,9 @@ makeGeneralFrameMapTable(MyThread* t, Context* context, uint8_t* start, pathIndex = subroutine->tableIndex; - THREAD_RUNTIME_ARRAY(t, SubroutineTrace*, traces, p->subroutineTraceCount); + THREAD_RUNTIME_ARRAY + (t, SubroutineTrace*, traces, p->subroutineTraceCount); + unsigned i = 0; for (SubroutineTrace* trace = p->subroutineTrace; trace; trace = trace->next) @@ -6795,9 +6802,9 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) // we must acquire the class lock here at the latest unsigned codeSize = c->resolve - (allocator->base + allocator->offset + BytesPerWord); + (allocator->base + allocator->offset + TargetBytesPerWord); - unsigned total = pad(codeSize) + pad(c->poolSize()) + BytesPerWord; + unsigned total = pad(codeSize) + pad(c->poolSize()) + TargetBytesPerWord; uintptr_t* code = static_cast(allocator->allocate(total)); code[0] = codeSize; @@ -6810,7 +6817,8 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) if (context->objectPool) { object pool = allocate3 (t, allocator, Machine::ImmortalAllocation, - FixedSizeOfArray + ((context->objectPoolCount + 1) * BytesPerWord), + FixedSizeOfArray + + ((context->objectPoolCount + 1) * TargetBytesPerWord), true); initArray(t, pool, context->objectPoolCount + 1); @@ -6821,7 +6829,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) unsigned i = 1; for (PoolElement* p = context->objectPool; p; p = p->next) { - unsigned offset = ArrayBody + ((i++) * BytesPerWord); + unsigned offset = ArrayBody + ((i++) * TargetBytesPerWord); p->address = reinterpret_cast(pool) + offset; @@ -7023,7 +7031,7 @@ compile(MyThread* t, Context* context) progress = false; for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); + uint64_t eh = exceptionHandlerTableBody(t, eht, i); int start = resolveIpForwards (context, exceptionHandlerStart(eh), exceptionHandlerEnd(eh)); @@ -7042,7 +7050,7 @@ compile(MyThread* t, Context* context) Frame frame2(&frame, RUNTIME_ARRAY_BODY(stackMap)); unsigned end = exceptionHandlerEnd(eh); - if (exceptionHandlerIp(eh) >= start + if (exceptionHandlerIp(eh) >= static_cast(start) and exceptionHandlerIp(eh) < end) { end = exceptionHandlerIp(eh); @@ -9334,15 +9342,15 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.default_.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(defaultContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); a->popFrame(t->arch->alignFrameSize(1)); Assembler::Register result(t->arch->returnLow()); - a->apply(Jump, BytesPerWord, RegisterOperand, &result); + a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result); p->thunks.default_.length = a->endBlock(false)->resolve(0, 0); } @@ -9355,38 +9363,38 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) Assembler::Memory virtualCallTargetSrc (t->arch->stack(), (t->arch->frameFooterSize() + t->arch->frameReturnAddressSize()) - * BytesPerWord); + * TargetBytesPerWord); - a->apply(Move, BytesPerWord, MemoryOperand, &virtualCallTargetSrc, - BytesPerWord, RegisterOperand, &class_); + a->apply(Move, TargetBytesPerWord, MemoryOperand, &virtualCallTargetSrc, + TargetBytesPerWord, RegisterOperand, &class_); Assembler::Memory virtualCallTargetDst (t->arch->thread(), difference(&(t->virtualCallTarget), t)); - a->apply(Move, BytesPerWord, RegisterOperand, &class_, - BytesPerWord, MemoryOperand, &virtualCallTargetDst); + a->apply(Move, TargetBytesPerWord, RegisterOperand, &class_, + TargetBytesPerWord, MemoryOperand, &virtualCallTargetDst); Assembler::Register index(t->arch->virtualCallIndex()); Assembler::Memory virtualCallIndex (t->arch->thread(), difference(&(t->virtualCallIndex), t)); - a->apply(Move, BytesPerWord, RegisterOperand, &index, - BytesPerWord, MemoryOperand, &virtualCallIndex); + a->apply(Move, TargetBytesPerWord, RegisterOperand, &index, + TargetBytesPerWord, MemoryOperand, &virtualCallIndex); a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t)); p->thunks.defaultVirtual.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(defaultVirtualContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); a->popFrame(t->arch->alignFrameSize(1)); Assembler::Register result(t->arch->returnLow()); - a->apply(Jump, BytesPerWord, RegisterOperand, &result); + a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result); p->thunks.defaultVirtual.length = a->endBlock(false)->resolve(0, 0); } @@ -9400,10 +9408,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.native.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(nativeContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); a->popFrameAndUpdateStackAndReturn (t->arch->alignFrameSize(1), difference(&(t->stack), t)); @@ -9420,10 +9428,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.aioob.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(aioobContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); p->thunks.aioob.length = a->endBlock(false)->resolve(0, 0); } @@ -9437,10 +9445,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.stackOverflow.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(stackOverflowContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); p->thunks.stackOverflow.length = a->endBlock(false)->resolve(0, 0); } @@ -9454,7 +9462,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.table.frameSavedOffset = a->length(); Assembler::Constant proc(&(tableContext.promise)); - a->apply(LongJump, BytesPerWord, ConstantOperand, &proc); + a->apply(LongJump, TargetBytesPerWord, ConstantOperand, &proc); p->thunks.table.length = a->endBlock(false)->resolve(0, 0); } @@ -9633,12 +9641,12 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size) ResolvedPromise indexPromise(index); Assembler::Constant indexConstant(&indexPromise); Assembler::Register indexRegister(t->arch->virtualCallIndex()); - a->apply(Move, BytesPerWord, ConstantOperand, &indexConstant, - BytesPerWord, RegisterOperand, &indexRegister); + a->apply(Move, TargetBytesPerWord, ConstantOperand, &indexConstant, + TargetBytesPerWord, RegisterOperand, &indexRegister); ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t)); Assembler::Constant thunk(&defaultVirtualThunkPromise); - a->apply(Jump, BytesPerWord, ConstantOperand, &thunk); + a->apply(Jump, TargetBytesPerWord, ConstantOperand, &thunk); *size = a->endBlock(false)->resolve(0, 0); @@ -9723,7 +9731,7 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext, // resolve all exception handler catch types before we acquire // the class lock: for (unsigned i = 0; i < exceptionHandlerTableLength(t, ehTable); ++i) { - ExceptionHandler* handler = exceptionHandlerTableBody(t, ehTable, i); + uint64_t handler = exceptionHandlerTableBody(t, ehTable, i); if (exceptionHandlerCatchType(handler)) { resolveClassInPool (t, clone, exceptionHandlerCatchType(handler) - 1); diff --git a/src/compiler.cpp b/src/compiler.cpp index 0b7e8d1917..157bb82d61 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -10,6 +10,7 @@ #include "compiler.h" #include "assembler.h" +#include "target.h" using namespace vm; @@ -34,7 +35,7 @@ const unsigned StealRegisterReserveCount = 2; // this should be equal to the largest number of registers used by a // compare instruction: -const unsigned ResolveRegisterReserveCount = (BytesPerWord == 8 ? 2 : 4); +const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4); const unsigned RegisterCopyCost = 1; const unsigned AddressCopyCost = 2; @@ -143,7 +144,7 @@ class Site { virtual SiteMask nextWordMask(Context*, unsigned) = 0; - virtual unsigned registerSize(Context*) { return BytesPerWord; } + virtual unsigned registerSize(Context*) { return TargetBytesPerWord; } virtual unsigned registerMask(Context*) { return 0; } @@ -467,8 +468,9 @@ class PoolPromise: public Promise { virtual int64_t value() { if (resolved()) { - return reinterpret_cast - (c->machineCode + pad(c->machineCodeSize) + (key * BytesPerWord)); + return reinterpret_cast + (c->machineCode + pad(c->machineCodeSize) + + (key * TargetBytesPerWord)); } abort(c); @@ -740,18 +742,18 @@ frameIndexToOffset(Context* c, unsigned frameIndex) { assert(c, frameIndex < totalFrameSize(c)); - return (frameIndex + c->arch->frameFooterSize()) * BytesPerWord; + return (frameIndex + c->arch->frameFooterSize()) * TargetBytesPerWord; } unsigned offsetToFrameIndex(Context* c, unsigned offset) { assert(c, static_cast - ((offset / BytesPerWord) - c->arch->frameFooterSize()) >= 0); - assert(c, ((offset / BytesPerWord) - c->arch->frameFooterSize()) + ((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0); + assert(c, ((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) < totalFrameSize(c)); - return (offset / BytesPerWord) - c->arch->frameFooterSize(); + return (offset / TargetBytesPerWord) - c->arch->frameFooterSize(); } unsigned @@ -837,7 +839,7 @@ class SiteIterator { Site** findNext(Site** p) { while (true) { if (*p) { - if (pass == 0 or (*p)->registerSize(c) > BytesPerWord) { + if (pass == 0 or (*p)->registerSize(c) > TargetBytesPerWord) { return p; } else { p = &((*p)->next); @@ -922,7 +924,7 @@ uniqueSite(Context* c, Value* v, Site* s) if (it.hasMore()) { // the site is not this word's only site, but if the site is // shared with the next word, it may be that word's only site - if (v->nextWord != v and s->registerSize(c) > BytesPerWord) { + if (v->nextWord != v and s->registerSize(c) > TargetBytesPerWord) { SiteIterator nit(c, v->nextWord); Site* p = nit.next(); if (nit.hasMore()) { @@ -1052,7 +1054,7 @@ deadWord(Context* c, Value* v) for (SiteIterator it(c, v, true, false); it.hasMore();) { Site* s = it.next(); - if (s->registerSize(c) > BytesPerWord) { + if (s->registerSize(c) > TargetBytesPerWord) { it.remove(c); addSite(c, nextWord, s); } @@ -1838,7 +1840,7 @@ class RegisterSite: public Site { RegisterSite* rs = static_cast(s); unsigned size = rs->registerSize(c); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { assert(c, number != NoRegister); return number == rs->number; } else { @@ -1940,7 +1942,7 @@ class RegisterSite: public Site { virtual SiteMask nextWordMask(Context* c, unsigned) { assert(c, number != NoRegister); - if (registerSize(c) > BytesPerWord) { + if (registerSize(c) > TargetBytesPerWord) { return SiteMask (1 << RegisterOperand, number, NoFrameIndex); } else { @@ -1955,7 +1957,7 @@ class RegisterSite: public Site { if ((1 << number) & c->arch->floatRegisterMask()) { return c->arch->floatRegisterSize(); } else { - return BytesPerWord; + return TargetBytesPerWord; } } @@ -2065,9 +2067,9 @@ class MemorySite: public Site { MemorySite* ms = static_cast(s); return ms->base == this->base and ((index == 1 and ms->offset == static_cast - (this->offset + BytesPerWord)) + (this->offset + TargetBytesPerWord)) or (index == 0 and this->offset == static_cast - (ms->offset + BytesPerWord))) + (ms->offset + TargetBytesPerWord))) and ms->index == this->index and ms->scale == this->scale; } else { @@ -2149,7 +2151,7 @@ class MemorySite: public Site { assert(c, high == this or (static_cast(high)->base == base and static_cast(high)->offset - == static_cast(offset + BytesPerWord) + == static_cast(offset + TargetBytesPerWord) and static_cast(high)->index == index and static_cast(high)->scale == scale)); @@ -2164,7 +2166,7 @@ class MemorySite: public Site { Site* copyHalf(Context* c, bool add) { if (add) { - return memorySite(c, base, offset + BytesPerWord, index, scale); + return memorySite(c, base, offset + TargetBytesPerWord, index, scale); } else { return copy(c); } @@ -2181,7 +2183,7 @@ class MemorySite: public Site { virtual Site* makeNextWord(Context* c, unsigned index) { return memorySite (c, base, offset + ((index == 1) xor c->arch->bigEndian() - ? BytesPerWord : -BytesPerWord), + ? TargetBytesPerWord : -TargetBytesPerWord), this->index, scale); } @@ -2398,7 +2400,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, unsigned registerReserveCount = 0) { Value* value = read->value; - unsigned size = value == value->nextWord ? BytesPerWord : 8; + unsigned size = value == value->nextWord ? TargetBytesPerWord : 8; class MyCostCalculator: public CostCalculator { public: @@ -2926,8 +2928,8 @@ move(Context* c, Value* value, Site* src, Site* dst) unsigned srcSize; unsigned dstSize; if (value->nextWord == value) { - srcSize = BytesPerWord; - dstSize = BytesPerWord; + srcSize = TargetBytesPerWord; + dstSize = TargetBytesPerWord; } else { srcSize = src->registerSize(c); dstSize = dst->registerSize(c); @@ -2935,7 +2937,7 @@ move(Context* c, Value* value, Site* src, Site* dst) if (srcSize == dstSize) { apply(c, Move, srcSize, src, src, dstSize, dst, dst); - } else if (srcSize > BytesPerWord) { + } else if (srcSize > TargetBytesPerWord) { Site* low, *high, *other = pickSiteOrGrow(c, value, dst, &low, &high); other->freeze(c, value->nextWord); @@ -3065,7 +3067,7 @@ addReads(Context* c, Event* e, Value* v, unsigned size, { SingleRead* r = read(c, lowMask, lowSuccessor); addRead(c, e, v, r); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { r->high_ = v->nextWord; addRead(c, e, v->nextWord, highMask, highSuccessor); } @@ -3234,7 +3236,7 @@ class CallEvent: public Event { uint8_t typeMask; uint64_t planRegisterMask; c->arch->plan - ((flags & Compiler::Aligned) ? AlignedCall : Call, BytesPerWord, + ((flags & Compiler::Aligned) ? AlignedCall : Call, TargetBytesPerWord, &typeMask, &planRegisterMask, &thunk); assert(c, not thunk); @@ -3251,10 +3253,11 @@ class CallEvent: public Event { Value* v = stack->value; stack = stack->next; - if ((BytesPerWord == 8 and (v == 0 or (i >= 1 and stack->value == 0))) - or (BytesPerWord == 4 and v->nextWord != v)) + if ((TargetBytesPerWord == 8 + and (v == 0 or (i >= 1 and stack->value == 0))) + or (TargetBytesPerWord == 4 and v->nextWord != v)) { - assert(c, BytesPerWord == 8 or v->nextWord == stack->value); + assert(c, TargetBytesPerWord == 8 or v->nextWord == stack->value); RUNTIME_ARRAY_BODY(arguments)[i--] = stack->value; stack = stack->next; @@ -3405,7 +3408,7 @@ class CallEvent: public Event { op = Call; } - apply(c, op, BytesPerWord, address->source, address->source); + apply(c, op, TargetBytesPerWord, address->source, address->source); if (traceHandler) { traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)), @@ -3436,7 +3439,7 @@ class CallEvent: public Event { if (resultSize and live(c, result)) { addSite(c, result, registerSite(c, c->arch->returnLow())); - if (resultSize > BytesPerWord and live(c, result->nextWord)) { + if (resultSize > TargetBytesPerWord and live(c, result->nextWord)) { addSite(c, result->nextWord, registerSite(c, c->arch->returnHigh())); } } @@ -3758,16 +3761,17 @@ class MoveEvent: public Event { bool noop = srcSelectSize >= dstSize; - if (dstSize > BytesPerWord) { + if (dstSize > TargetBytesPerWord) { grow(c, dst); } - if (srcSelectSize > BytesPerWord) { + if (srcSelectSize > TargetBytesPerWord) { maybeSplit(c, src); } addReads(c, this, src, srcSelectSize, srcLowMask, noop ? dst : 0, - srcHighMask, noop and dstSize > BytesPerWord ? dst->nextWord : 0); + srcHighMask, + noop and dstSize > TargetBytesPerWord ? dst->nextWord : 0); } virtual const char* name() { @@ -3791,43 +3795,46 @@ class MoveEvent: public Event { SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex); SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex); - if (srcSelectSize >= BytesPerWord - and dstSize >= BytesPerWord + if (srcSelectSize >= TargetBytesPerWord + and dstSize >= TargetBytesPerWord and srcSelectSize >= dstSize) { if (dst->target) { - if (dstSize > BytesPerWord - and src->source->registerSize(c) > BytesPerWord) + if (dstSize > TargetBytesPerWord + and src->source->registerSize(c) > TargetBytesPerWord) { apply(c, Move, srcSelectSize, src->source, src->source, dstSize, dst->target, dst->target); if (live(c, dst) == 0) { removeSite(c, dst, dst->target); - if (dstSize > BytesPerWord) { + if (dstSize > TargetBytesPerWord) { removeSite(c, dst->nextWord, dst->nextWord->target); } } } else { - maybeMove(c, Move, BytesPerWord, BytesPerWord, src, - BytesPerWord, dst, dstLowMask); - if (dstSize > BytesPerWord) { - maybeMove(c, Move, BytesPerWord, BytesPerWord, src->nextWord, - BytesPerWord, dst->nextWord, dstHighMask); + maybeMove(c, Move, TargetBytesPerWord, TargetBytesPerWord, src, + TargetBytesPerWord, dst, dstLowMask); + if (dstSize > TargetBytesPerWord) { + maybeMove + (c, Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord, + TargetBytesPerWord, dst->nextWord, dstHighMask); } } } else { Site* low = pickSiteOrMove(c, src, dst, 0, 0); - if (dstSize > BytesPerWord) { + if (dstSize > TargetBytesPerWord) { pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1); } } - } else if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) { + } else if (srcSelectSize <= TargetBytesPerWord + and dstSize <= TargetBytesPerWord) + { maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst, dstLowMask); } else { - assert(c, srcSize == BytesPerWord); - assert(c, srcSelectSize == BytesPerWord); + assert(c, srcSize == TargetBytesPerWord); + assert(c, srcSelectSize == TargetBytesPerWord); if (dst->nextWord->target or live(c, dst->nextWord)) { assert(c, dstLowMask.typeMask & (1 << RegisterOperand)); @@ -3847,8 +3854,8 @@ class MoveEvent: public Event { srcb, dstb, src); } - apply(c, Move, BytesPerWord, src->source, src->source, - BytesPerWord, low, low); + apply(c, Move, TargetBytesPerWord, src->source, src->source, + TargetBytesPerWord, low, low); low->thaw(c, dst); @@ -3871,7 +3878,7 @@ class MoveEvent: public Event { srcb, dstb, dst, dst->nextWord); } - apply(c, Move, BytesPerWord, low, low, dstSize, low, high); + apply(c, Move, TargetBytesPerWord, low, low, dstSize, low, high); high->thaw(c, dst->nextWord); @@ -3972,7 +3979,7 @@ void freezeSource(Context* c, unsigned size, Value* v) { v->source->freeze(c, v); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { v->nextWord->source->freeze(c, v->nextWord); } } @@ -3981,7 +3988,7 @@ void thawSource(Context* c, unsigned size, Value* v) { v->source->thaw(c, v); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { v->nextWord->source->thaw(c, v->nextWord); } } @@ -4002,7 +4009,7 @@ class CombineEvent: public Event { { addReads(c, this, first, firstSize, firstLowMask, firstHighMask); - if (resultSize > BytesPerWord) { + if (resultSize > TargetBytesPerWord) { grow(c, result); } @@ -4227,7 +4234,7 @@ push(Context* c, unsigned footprint, Value* v) if (footprint > 1) { assert(c, footprint == 2); - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { maybeSplit(c, low); high = pushWord(c, low->nextWord); } else { @@ -4288,9 +4295,9 @@ pop(Context* c, unsigned footprint) high = low->next; } - assert(c, (BytesPerWord == 8 + assert(c, (TargetBytesPerWord == 8 and low->value->nextWord == low->value and high->value == 0) - or (BytesPerWord == 4 and low->value->nextWord == high->value)); + or (TargetBytesPerWord == 4 and low->value->nextWord == high->value)); #endif // not NDEBUG popWord(c); @@ -4331,7 +4338,7 @@ storeLocal(Context* c, unsigned footprint, Value* v, unsigned index, bool copy) highIndex = index; } - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { assert(c, v->nextWord != v); high = storeLocal(c, 1, v->nextWord, highIndex, false); @@ -4423,11 +4430,11 @@ appendCombine(Context* c, TernaryOperation type, intptr_t handler = c->client->getThunk (type, firstSize, resultSize, &threadParameter); - unsigned stackSize = ceiling(secondSize, BytesPerWord) - + ceiling(firstSize, BytesPerWord); + unsigned stackSize = ceiling(secondSize, TargetBytesPerWord) + + ceiling(firstSize, TargetBytesPerWord); - local::push(c, ceiling(secondSize, BytesPerWord), second); - local::push(c, ceiling(firstSize, BytesPerWord), first); + local::push(c, ceiling(secondSize, TargetBytesPerWord), second); + local::push(c, ceiling(firstSize, TargetBytesPerWord), first); if (threadParameter) { ++ stackSize; @@ -4467,7 +4474,7 @@ class TranslateEvent: public Event { { bool condensed = c->arch->alwaysCondensed(type); - if (resultSize > BytesPerWord) { + if (resultSize > TargetBytesPerWord) { grow(c, result); } @@ -4549,7 +4556,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, if (thunk) { Stack* oldStack = c->stack; - local::push(c, ceiling(firstSize, BytesPerWord), first); + local::push(c, ceiling(firstSize, TargetBytesPerWord), first); Stack* argumentStack = c->stack; c->stack = oldStack; @@ -4559,7 +4566,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, (c, ValueGeneral, constantSite (c, c->client->getThunk(type, firstSize, resultSize))), 0, 0, result, resultSize, argumentStack, - ceiling(firstSize, BytesPerWord), 0); + ceiling(firstSize, TargetBytesPerWord), 0); } else { append(c, new (c->zone->allocate(sizeof(TranslateEvent))) TranslateEvent @@ -4632,7 +4639,7 @@ class MemoryEvent: public Event { popRead(c, this, base); if (index) { - if (BytesPerWord == 8 and indexRegister != NoRegister) { + if (TargetBytesPerWord == 8 and indexRegister != NoRegister) { apply(c, Move, 4, index->source, index->source, 8, index->source, index->source); } @@ -4798,7 +4805,7 @@ class BranchEvent: public Event { uint8_t typeMask; uint64_t registerMask; - c->arch->planDestination(type, size, 0, 0, size, 0, 0, BytesPerWord, + c->arch->planDestination(type, size, 0, 0, size, 0, 0, TargetBytesPerWord, &typeMask, ®isterMask); addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); @@ -4821,7 +4828,7 @@ class BranchEvent: public Event { int64_t firstValue = firstConstant->value->value(); int64_t secondValue = secondConstant->value->value(); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { firstValue |= findConstantSite (c, first->nextWord)->value->value() << 32; secondValue |= findConstantSite @@ -4829,18 +4836,18 @@ class BranchEvent: public Event { } if (shouldJump(c, type, size, firstValue, secondValue)) { - apply(c, Jump, BytesPerWord, address->source, address->source); + apply(c, Jump, TargetBytesPerWord, address->source, address->source); } } else { freezeSource(c, size, first); freezeSource(c, size, second); - freezeSource(c, BytesPerWord, address); + freezeSource(c, TargetBytesPerWord, address); apply(c, type, size, first->source, first->nextWord->source, size, second->source, second->nextWord->source, - BytesPerWord, address->source, address->source); + TargetBytesPerWord, address->source, address->source); - thawSource(c, BytesPerWord, address); + thawSource(c, TargetBytesPerWord, address); thawSource(c, size, second); thawSource(c, size, first); } @@ -4872,7 +4879,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask, size, &secondTypeMask, &secondRegisterMask, - BytesPerWord, &thunk); + TargetBytesPerWord, &thunk); if (thunk) { Stack* oldStack = c->stack; @@ -4883,8 +4890,8 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, assert(c, not threadParameter); - local::push(c, ceiling(size, BytesPerWord), second); - local::push(c, ceiling(size, BytesPerWord), first); + local::push(c, ceiling(size, TargetBytesPerWord), second); + local::push(c, ceiling(size, TargetBytesPerWord), first); Stack* argumentStack = c->stack; c->stack = oldStack; @@ -4893,7 +4900,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, appendCall (c, value (c, ValueGeneral, constantSite(c, handler)), 0, 0, result, 4, - argumentStack, ceiling(size, BytesPerWord) * 2, 0); + argumentStack, ceiling(size, TargetBytesPerWord) * 2, 0); appendBranch(c, thunkBranch(c, type), 4, value (c, ValueGeneral, constantSite(c, static_cast(0))), @@ -4920,7 +4927,7 @@ class JumpEvent: public Event { bool thunk; uint8_t typeMask; uint64_t registerMask; - c->arch->plan(type, BytesPerWord, &typeMask, ®isterMask, &thunk); + c->arch->plan(type, TargetBytesPerWord, &typeMask, ®isterMask, &thunk); assert(c, not thunk); @@ -4933,7 +4940,7 @@ class JumpEvent: public Event { virtual void compile(Context* c) { if (not unreachable(this)) { - apply(c, type, BytesPerWord, address->source, address->source); + apply(c, type, TargetBytesPerWord, address->source, address->source); } for (Read* r = reads; r; r = r->eventNext) { @@ -4992,7 +4999,7 @@ class BoundsCheckEvent: public Event { if (constant) { if (constant->value->value() < 0) { Assembler::Constant handlerConstant(resolved(c, handler)); - a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant); + a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant); } } else { outOfBoundsPromise = codePromise(c, static_cast(0)); @@ -5000,7 +5007,7 @@ class BoundsCheckEvent: public Event { ConstantSite zero(resolved(c, 0)); ConstantSite oob(outOfBoundsPromise); apply(c, JumpIfLess, 4, &zero, &zero, 4, index->source, index->source, - BytesPerWord, &oob, &oob); + TargetBytesPerWord, &oob, &oob); } if (constant == 0 or constant->value->value() >= 0) { @@ -5011,20 +5018,20 @@ class BoundsCheckEvent: public Event { CodePromise* nextPromise = codePromise(c, static_cast(0)); - freezeSource(c, BytesPerWord, index); + freezeSource(c, TargetBytesPerWord, index); ConstantSite next(nextPromise); apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length, - &length, BytesPerWord, &next, &next); + &length, TargetBytesPerWord, &next, &next); - thawSource(c, BytesPerWord, index); + thawSource(c, TargetBytesPerWord, index); if (constant == 0) { outOfBoundsPromise->offset = a->offset(); } Assembler::Constant handlerConstant(resolved(c, handler)); - a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant); + a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant); nextPromise->offset = a->offset(); } @@ -6268,7 +6275,7 @@ class MyCompiler: public Compiler { virtual void save(unsigned footprint, Operand* value) { c.saved = cons(&c, static_cast(value), c.saved); - if (BytesPerWord == 4 and footprint > 1) { + if (TargetBytesPerWord == 4 and footprint > 1) { assert(&c, footprint == 2); assert(&c, static_cast(value)->nextWord); @@ -6329,9 +6336,10 @@ class MyCompiler: public Compiler { high = s->next; } - assert(&c, (BytesPerWord == 8 + assert(&c, (TargetBytesPerWord == 8 and low->value->nextWord == low->value and high->value == 0) - or (BytesPerWord == 4 and low->value->nextWord == high->value)); + or (TargetBytesPerWord == 4 + and low->value->nextWord == high->value)); #endif // not NDEBUG if (bigEndian) { @@ -6355,20 +6363,20 @@ class MyCompiler: public Compiler { bool bigEndian = c.arch->bigEndian(); unsigned footprint = 0; - unsigned size = BytesPerWord; + unsigned size = TargetBytesPerWord; RUNTIME_ARRAY(Value*, arguments, argumentCount); int index = 0; for (unsigned i = 0; i < argumentCount; ++i) { Value* o = va_arg(a, Value*); if (o) { - if (bigEndian and size > BytesPerWord) { + if (bigEndian and size > TargetBytesPerWord) { RUNTIME_ARRAY_BODY(arguments)[index++] = o->nextWord; } RUNTIME_ARRAY_BODY(arguments)[index] = o; - if ((not bigEndian) and size > BytesPerWord) { + if ((not bigEndian) and size > TargetBytesPerWord) { RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord; } - size = BytesPerWord; + size = TargetBytesPerWord; ++ index; } else { size = 8; @@ -6427,7 +6435,7 @@ class MyCompiler: public Compiler { highIndex = index; } - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { initLocal(1, highIndex, type); Value* next = c.locals[highIndex].value; v->nextWord = next; @@ -6499,7 +6507,7 @@ class MyCompiler: public Compiler { virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src, unsigned dstSize) { - assert(&c, dstSize >= BytesPerWord); + assert(&c, dstSize >= TargetBytesPerWord); Value* dst = value(&c, static_cast(src)->type); appendMove(&c, Move, srcSize, srcSelectSize, static_cast(src), @@ -6510,7 +6518,7 @@ class MyCompiler: public Compiler { virtual Operand* loadz(unsigned srcSize, unsigned srcSelectSize, Operand* src, unsigned dstSize) { - assert(&c, dstSize >= BytesPerWord); + assert(&c, dstSize >= TargetBytesPerWord); Value* dst = value(&c, static_cast(src)->type); appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast(src), @@ -6786,7 +6794,7 @@ class MyCompiler: public Compiler { virtual Operand* shl(unsigned size, Operand* a, Operand* b) { assert(&c, static_cast(a)->type == ValueGeneral); Value* result = value(&c, ValueGeneral); - appendCombine(&c, ShiftLeft, BytesPerWord, static_cast(a), + appendCombine(&c, ShiftLeft, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } @@ -6794,7 +6802,7 @@ class MyCompiler: public Compiler { virtual Operand* shr(unsigned size, Operand* a, Operand* b) { assert(&c, static_cast(a)->type == ValueGeneral); Value* result = value(&c, ValueGeneral); - appendCombine(&c, ShiftRight, BytesPerWord, static_cast(a), + appendCombine(&c, ShiftRight, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } @@ -6803,8 +6811,8 @@ class MyCompiler: public Compiler { assert(&c, static_cast(a)->type == ValueGeneral); Value* result = value(&c, ValueGeneral); appendCombine - (&c, UnsignedShiftRight, BytesPerWord, static_cast(a), size, - static_cast(b), size, result); + (&c, UnsignedShiftRight, TargetBytesPerWord, static_cast(a), + size, static_cast(b), size, result); return result; } @@ -6933,7 +6941,7 @@ class MyCompiler: public Compiler { } virtual unsigned poolSize() { - return c.constantCount * BytesPerWord; + return c.constantCount * TargetBytesPerWord; } virtual void write() { @@ -6962,7 +6970,7 @@ class MyCompiler: public Compiler { new (n->promise->listen(sizeof(Listener))) Listener(target); } - i += BytesPerWord; + i += TargetBytesPerWord; } } diff --git a/src/heap.cpp b/src/heap.cpp index be26c9ea3e..8208cd7e73 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -19,12 +19,6 @@ namespace { namespace local { -// an object must survive TenureThreshold + 2 garbage collections -// before being copied to gen2 (must be at least 1): -const unsigned TenureThreshold = 3; - -const unsigned FixieTenureThreshold = TenureThreshold + 2; - const unsigned Top = ~static_cast(0); const unsigned InitialGen2CapacityInBytes = 4 * 1024 * 1024; @@ -546,11 +540,14 @@ class Fixie { return totalSize(size, hasMask); } + // be sure to update e.g. TargetFixieSizeInBytes in bootimage.cpp if + // you add/remove/change fields in this class: + uint8_t age; bool hasMask; bool marked; bool dirty; - unsigned size; + uint32_t size; Fixie* next; Fixie** handle; uintptr_t body_[0]; diff --git a/src/heap.h b/src/heap.h index ecb60d2637..838d88786c 100644 --- a/src/heap.h +++ b/src/heap.h @@ -16,6 +16,12 @@ namespace vm { +// an object must survive TenureThreshold + 2 garbage collections +// before being copied to gen2 (must be at least 1): +const unsigned TenureThreshold = 3; + +const unsigned FixieTenureThreshold = TenureThreshold + 2; + class Heap: public Allocator { public: enum CollectionType { diff --git a/src/interpret.cpp b/src/interpret.cpp index b5810a434e..255977c25d 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -665,7 +665,7 @@ store(Thread* t, unsigned index) BytesPerWord * 2); } -ExceptionHandler* +uint64_t findExceptionHandler(Thread* t, object method, unsigned ip) { PROTECT(t, method); @@ -674,7 +674,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip) if (eht) { for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); + uint64_t eh = exceptionHandlerTableBody(t, eht, i); if (ip - 1 >= exceptionHandlerStart(eh) and ip - 1 < exceptionHandlerEnd(eh)) @@ -708,7 +708,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip) return 0; } -ExceptionHandler* +uint64_t findExceptionHandler(Thread* t, int frame) { return findExceptionHandler(t, frameMethod(t, frame), frameIp(t, frame)); @@ -2673,7 +2673,7 @@ interpret3(Thread* t, const int base) pokeInt(t, t->frame + FrameIpOffset, t->ip); for (; frame >= base; popFrame(t)) { - ExceptionHandler* eh = findExceptionHandler(t, frame); + uint64_t eh = findExceptionHandler(t, frame); if (eh) { sp = frame + FrameFootprint; ip = exceptionHandlerIp(eh); diff --git a/src/machine.cpp b/src/machine.cpp index 9168c09019..0219894f77 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1143,11 +1143,10 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) addendum, class_); + unsigned size = fieldSize(t, code); if (flags & ACC_STATIC) { - unsigned size = fieldSize(t, code); - unsigned excess = (staticOffset % size) % BytesPerWord; - if (excess) { - staticOffset += BytesPerWord - excess; + while (staticOffset % size) { + ++ staticOffset; } fieldOffset(t, field) = staticOffset; @@ -1162,12 +1161,13 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) classVmFlags(t, class_) |= HasFinalMemberFlag; } - while (memberOffset % fieldSize(t, code)) { + while (memberOffset % size) { ++ memberOffset; } fieldOffset(t, field) = memberOffset; - memberOffset += fieldSize(t, code); + + memberOffset += size; } set(t, fieldTable, ArrayBody + (i * BytesPerWord), field); @@ -1298,11 +1298,12 @@ parseCode(Thread* t, Stream& s, object pool) if (ehtLength) { object eht = makeExceptionHandlerTable(t, ehtLength); for (unsigned i = 0; i < ehtLength; ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); - exceptionHandlerStart(eh) = s.read2(); - exceptionHandlerEnd(eh) = s.read2(); - exceptionHandlerIp(eh) = s.read2(); - exceptionHandlerCatchType(eh) = s.read2(); + unsigned start = s.read2(); + unsigned end = s.read2(); + unsigned ip = s.read2(); + unsigned catchType = s.read2(); + exceptionHandlerTableBody(t, eht, i) = exceptionHandler + (start, end, ip, catchType); } set(t, code, CodeExceptionHandlerTable, eht); @@ -1319,9 +1320,9 @@ parseCode(Thread* t, Stream& s, object pool) unsigned lntLength = s.read2(); object lnt = makeLineNumberTable(t, lntLength); for (unsigned i = 0; i < lntLength; ++i) { - LineNumber* ln = lineNumberTableBody(t, lnt, i); - lineNumberIp(ln) = s.read2(); - lineNumberLine(ln) = s.read2(); + unsigned ip = s.read2(); + unsigned line = s.read2(); + lineNumberTableBody(t, lnt, i) = lineNumber(ip, line); } set(t, code, CodeLineNumberTable, lnt); @@ -2217,9 +2218,9 @@ boot(Thread* t) #include "type-java-initializations.cpp" -#ifdef AVIAN_HEAPDUMP + //#ifdef AVIAN_HEAPDUMP # include "type-name-initializations.cpp" -#endif + //#endif } } @@ -3428,6 +3429,16 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size, updateClassTables(t, real, class_); + if (root(t, Machine::PoolMap)) { + object bootstrapClass = hashMapFind + (t, root(t, Machine::BootstrapClassMap), className(t, class_), + byteArrayHash, byteArrayEqual); + + hashMapInsert + (t, root(t, Machine::PoolMap), bootstrapClass ? bootstrapClass : real, + pool, objectHash); + } + return real; } @@ -4426,7 +4437,7 @@ vmAddressFromLine(Thread* t, object m, unsigned line) unsigned top = lineNumberTableLength(t, lnt); for(unsigned i = bottom; i < top; i++) { - LineNumber* ln = lineNumberTableBody(t, lnt, i); + uint64_t ln = lineNumberTableBody(t, lnt, i); if(lineNumberLine(ln) == line) return reinterpret_cast(lineNumberIp(ln)); else if(lineNumberLine(ln) > line) diff --git a/src/machine.h b/src/machine.h index 28a3a764f1..1b53c9f8d8 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1253,6 +1253,7 @@ class Machine { MonitorMap, StringMap, ByteArrayMap, + PoolMap, ClassRuntimeDataTable, MethodRuntimeDataTable, JNIMethodTable, @@ -3283,14 +3284,20 @@ methodVirtual(Thread* t, object method) } inline unsigned -singletonMaskSize(unsigned count) +singletonMaskSize(unsigned count, unsigned bitsPerWord) { if (count) { - return ceiling(count + 2, BitsPerWord); + return ceiling(count + 2, bitsPerWord); } return 0; } +inline unsigned +singletonMaskSize(unsigned count) +{ + return singletonMaskSize(count, BitsPerWord); +} + inline unsigned singletonMaskSize(Thread* t, object singleton) { @@ -3315,11 +3322,17 @@ singletonMask(Thread* t, object singleton) (&singletonBody(t, singleton, singletonCount(t, singleton))); } +inline void +singletonMarkObject(uint32_t* mask, unsigned index) +{ + mask[(index + 2) / 32] + |= (static_cast(1) << ((index + 2) % 32)); +} + inline void singletonMarkObject(Thread* t, object singleton, unsigned index) { - singletonMask(t, singleton)[(index + 2) / 32] - |= (static_cast(1) << ((index + 2) % 32)); + singletonMarkObject(singletonMask(t, singleton), index); } inline bool @@ -3370,10 +3383,16 @@ singletonBit(Thread* t, object singleton, unsigned start, unsigned index) & (static_cast(1) << (index % BitsPerWord))) != 0; } +inline unsigned +poolMaskSize(unsigned count, unsigned bitsPerWord) +{ + return ceiling(count, bitsPerWord); +} + inline unsigned poolMaskSize(unsigned count) { - return ceiling(count, BitsPerWord); + return poolMaskSize(count, BitsPerWord); } inline unsigned @@ -3766,6 +3785,54 @@ methodClone(Thread* t, object method) methodCode(t, method)); } +inline uint64_t +exceptionHandler(uint64_t start, uint64_t end, uint64_t ip, uint64_t catchType) +{ + return (start << 48) | (end << 32) | (ip << 16) | catchType; +} + +inline unsigned +exceptionHandlerStart(uint64_t eh) +{ + return eh >> 48; +} + +inline unsigned +exceptionHandlerEnd(uint64_t eh) +{ + return (eh >> 32) & 0xFFFF; +} + +inline unsigned +exceptionHandlerIp(uint64_t eh) +{ + return (eh >> 16) & 0xFFFF; +} + +inline unsigned +exceptionHandlerCatchType(uint64_t eh) +{ + return eh & 0xFFFF; +} + +inline uint64_t +lineNumber(uint64_t ip, uint64_t line) +{ + return (ip << 32) | line; +} + +inline unsigned +lineNumberIp(uint64_t ln) +{ + return ln >> 32; +} + +inline unsigned +lineNumberLine(uint64_t ln) +{ + return ln & 0xFFFFFFFF; +} + inline FILE* errorLog(Thread* t) { diff --git a/src/process.cpp b/src/process.cpp index d2aebb131d..ac1c21917e 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -271,7 +271,7 @@ findLineNumber(Thread* t, object method, unsigned ip) unsigned top = lineNumberTableLength(t, lnt); for (unsigned span = top - bottom; span; span = top - bottom) { unsigned middle = bottom + (span / 2); - LineNumber* ln = lineNumberTableBody(t, lnt, middle); + uint64_t ln = lineNumberTableBody(t, lnt, middle); if (ip >= lineNumberIp(ln) and (middle + 1 == lineNumberTableLength(t, lnt) diff --git a/src/target.h b/src/target.h new file mode 100644 index 0000000000..91244b7ed6 --- /dev/null +++ b/src/target.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2011, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#ifndef TARGET_H +#define TARGET_H + +#define TARGET_V1(v) (v) + +#ifdef TARGET_OPPOSITE_ENDIAN +# define TARGET_V2(v) \ + ((((v) >> 8) & 0xFF) | \ + (((v) << 8))) +# define TARGET_V4(v) \ + ((((v) >> 24) & 0x000000FF) | \ + (((v) >> 8) & 0x0000FF00) | \ + (((v) << 8) & 0x00FF0000) | \ + (((v) << 24))) +# define TARGET_V8(v) \ + (((static_cast(v) >> 56) & UINT64_C(0x00000000000000FF)) | \ + ((static_cast(v) >> 40) & UINT64_C(0x000000000000FF00)) | \ + ((static_cast(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \ + ((static_cast(v) >> 8) & UINT64_C(0x00000000FF000000)) | \ + ((static_cast(v) << 8) & UINT64_C(0x000000FF00000000)) | \ + ((static_cast(v) << 24) & UINT64_C(0x0000FF0000000000)) | \ + ((static_cast(v) << 40) & UINT64_C(0x00FF000000000000)) | \ + ((static_cast(v) << 56))) +#else +# define TARGET_V2(v) (v) +# define TARGET_V4(v) (v) +# define TARGET_V8(v) (v) +#endif + +namespace vm { + +#ifdef TARGET_BYTES_PER_WORD +# if (TARGET_BYTES_PER_WORD == 8) +# define TARGET_VW(v) TARGET_V8(v) +typedef uint64_t target_uintptr_t; +typedef int64_t target_intptr_t; +const unsigned TargetBytesPerWord = 8; +# elif (TARGET_BYTES_PER_WORD == 4) +# define TARGET_VW(v) TARGET_V4(v) +typedef uint32_t target_uintptr_t; +typedef int32_t target_intptr_t; +const unsigned TargetBytesPerWord = 4; +# else +# error +# endif +#else +typedef uintptr_t target_uintptr_t; +typedef intptr_t target_intptr_t; +const unsigned TargetBytesPerWord = BytesPerWord; +#endif + +const unsigned TargetBitsPerWord = TargetBytesPerWord * 8; + +} // namespace vm + +#endif//TARGET_H diff --git a/src/type-generator.cpp b/src/type-generator.cpp index 626573af8e..eb0141f215 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -225,7 +225,6 @@ class Object { Scalar, Array, Method, - Pod, Type, Pair, Number, @@ -314,20 +313,18 @@ class List { class Scalar : public Object { public: Object* owner; - Object* typeObject; const char* typeName; const char* name; unsigned elementSize; bool noassert; bool nogc; - static Scalar* make(Object* owner, Object* typeObject, const char* typeName, - const char* name, unsigned size) + static Scalar* make(Object* owner, const char* typeName, const char* name, + unsigned size) { Scalar* o = allocate(); o->type = Object::Scalar; o->owner = owner; - o->typeObject = typeObject; o->typeName = typeName; o->name = name; o->elementSize = size; @@ -339,13 +336,12 @@ class Scalar : public Object { class Array : public Scalar { public: - static Array* make(Object* owner, Object* typeObject, const char* typeName, - const char* name, unsigned elementSize) + static Array* make(Object* owner, const char* typeName, const char* name, + unsigned elementSize) { Array* o = allocate(); o->type = Object::Array; o->owner = owner; - o->typeObject = typeObject; o->typeName = typeName; o->name = name; o->elementSize = elementSize; @@ -380,19 +376,6 @@ memberOwner(Object* o) } } -Object* -memberTypeObject(Object* o) -{ - switch (o->type) { - case Object::Scalar: - case Object::Array: - return static_cast(o)->typeObject; - - default: - UNREACHABLE; - } -} - const char* memberTypeName(Object* o) { @@ -406,6 +389,17 @@ memberTypeName(Object* o) } } +const char* +memberTypeEnumName(Object* o) +{ + const char* n = memberTypeName(o); + if (strcmp("void*", n) == 0) { + return "word"; + } else { + return n; + } +} + const char*& memberName(Object* o) { @@ -545,7 +539,7 @@ const char* typeName(Object* o) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: return static_cast(o)->name; default: @@ -557,7 +551,7 @@ const char* typeJavaName(Object* o) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: return static_cast(o)->javaName; default: @@ -569,7 +563,7 @@ Object* typeMembers(Object* o) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: return static_cast(o)->members.first; default: @@ -605,10 +599,10 @@ void addMember(Object* o, Object* member) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: if (member->type == Object::Array) { static_cast(o)->members.append - (Scalar::make(o, 0, "uintptr_t", "length", BytesPerWord)); + (Scalar::make(o, "uintptr_t", "length", BytesPerWord)); } static_cast(o)->members.append(member); break; @@ -822,7 +816,7 @@ declaration(const char* name, Object* declarations) for (Object* p = declarations; p; p = cdr(p)) { Object* o = car(p); switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: if (equal(name, typeName(o))) return o; break; @@ -842,9 +836,6 @@ javaDeclaration(const char* name, Object* declarations) if (typeJavaName(o) and equal(name, typeJavaName(o))) return o; break; - case Object::Pod: - break; - default: UNREACHABLE; } } @@ -854,15 +845,11 @@ javaDeclaration(const char* name, Object* declarations) Object* derivationChain(Object* o) { - if (o->type == Object::Pod) { - return cons(o, 0); - } else { - Object* chain = 0; - for (Object* p = o; p; p = typeSuper(p)) { - chain = cons(p, chain); - } - return chain; + Object* chain = 0; + for (Object* p = o; p; p = typeSuper(p)) { + chain = cons(p, chain); } + return chain; } class MemberIterator { @@ -883,7 +870,7 @@ class MemberIterator { members(0), member(0), index_(-1), - offset_(type->type == Object::Pod ? 0 : BytesPerWord), + offset_(BytesPerWord), size_(0), padding_(0), alignment_(BytesPerWord) @@ -972,21 +959,6 @@ class MemberIterator { } }; -unsigned -typeSize(Object* o) -{ - switch (o->type) { - case Object::Pod: { - MemberIterator it(o); - while (it.hasMore()) it.next(); - return pad(it.offset() + it.space()); - } break; - - default: - UNREACHABLE; - } -} - bool namesPointer(const char* s) { @@ -996,7 +968,7 @@ namesPointer(const char* s) } unsigned -sizeOf(const char* type, Object* declarations) +sizeOf(const char* type) { if (equal(type, "object") or equal(type, "intptr_t") or equal(type, "uintptr_t")) @@ -1021,33 +993,29 @@ sizeOf(const char* type, Object* declarations) } else if (namesPointer(type)) { return BytesPerWord; } else { - Object* dec = declaration(type, declarations); - if (dec) return typeSize(dec); - fprintf(stderr, "unexpected type: %s\n", type); abort(); } } Object* -parseArray(Object* t, Object* p, Object* declarations) +parseArray(Object* t, Object* p) { const char* typeName = string(car(p)); p = cdr(p); const char* name = string(car(p)); - return Array::make(t, declaration(typeName, declarations), - typeName, name, sizeOf(typeName, declarations)); + return Array::make(t, typeName, name, sizeOf(typeName)); } Object* -parseMember(Object* t, Object* p, Object* declarations); +parseMember(Object* t, Object* p); Object* -parseMember(Object* t, Object* p, Object* declarations, bool* isNew) +parseMember(Object* t, Object* p, bool* isNew) { - Object* member = parseMember(t, p, declarations); + Object* member = parseMember(t, p); for (MemberIterator it(t); it.hasMore();) { Object* m = it.next(); if (equal(memberName(m), memberName(member))) { @@ -1063,34 +1031,32 @@ parseMember(Object* t, Object* p, Object* declarations, bool* isNew) } Object* -parseMember(Object* t, Object* p, Object* declarations) +parseMember(Object* t, Object* p) { const char* spec = string(car(p)); if (equal(spec, "array")) { - return parseArray(t, cdr(p), declarations); + return parseArray(t, cdr(p)); } else if (equal(spec, "noassert")) { bool isNew; - Object* member = parseMember(t, cdr(p), declarations, &isNew); + Object* member = parseMember(t, cdr(p), &isNew); memberNoAssert(member) = true; return isNew ? member : 0; } else if (equal(spec, "nogc")) { bool isNew; - Object* member = parseMember(t, cdr(p), declarations, &isNew); + Object* member = parseMember(t, cdr(p), &isNew); memberNoGC(member) = true; return isNew ? member : 0; } else if (equal(spec, "require")) { bool isNew; - Object* member = parseMember(t, cdr(p), declarations, &isNew); + Object* member = parseMember(t, cdr(p), &isNew); return isNew ? member : 0; } else if (equal(spec, "alias")) { bool isNew; - Object* member = parseMember(t, cdr(cdr(p)), declarations, &isNew); + Object* member = parseMember(t, cdr(cdr(p)), &isNew); memberName(member) = string(car(cdr(p))); return 0; } else { - return Scalar::make(t, declaration(spec, declarations), spec, - string(car(cdr(p))), - sizeOf(spec, declarations)); + return Scalar::make(t, spec, string(car(cdr(p))), sizeOf(spec)); } } @@ -1105,7 +1071,7 @@ parseSubdeclaration(Object* t, Object* p, Object* declarations) assert(typeSuper(t)); assert(typeSuper(t)->type == Object::Type); } else { - Object* member = parseMember(t, p, declarations); + Object* member = parseMember(t, p); if (member) { addMember(t, member); } @@ -1297,7 +1263,7 @@ parseJavaClass(Object* type, Stream* s, Object* declarations) const char* memberType = fieldType(spec); Object* member = Scalar::make - (type, 0, memberType, name, sizeOf(memberType, declarations)); + (type, memberType, name, sizeOf(memberType)); addMember(type, member); } @@ -1365,7 +1331,7 @@ parseType(Finder* finder, Object::ObjectType type, Object* p, if (type == Object::Type) { parseSubdeclaration(t, car(p), declarations); } else { - Object* member = parseMember(t, car(p), declarations); + Object* member = parseMember(t, car(p)); if (member) { assert(member->type == Object::Scalar); addMember(t, member); @@ -1390,8 +1356,6 @@ parseDeclaration(Finder* finder, Object* p, Object* declarations) const char* spec = string(car(p)); if (equal(spec, "type")) { return parseType(finder, Object::Type, cdr(p), declarations); - } else if (equal(spec, "pod")) { - return parseType(finder, Object::Pod, cdr(p), declarations); } else { fprintf(stderr, "unexpected declaration spec: %s\n", spec); abort(); @@ -1473,7 +1437,6 @@ void writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) { const char* typeName = memberTypeName(member); - if (memberTypeObject(member)) typeName = capitalize(typeName); if (not unsafe) { out->write("const unsigned "); @@ -1491,22 +1454,12 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) out->write("*"); } else { out->write(typeName); - if (member->type != Object::Scalar and memberTypeObject(member)) { - out->write("*"); - } else { - out->write("&"); - } + out->write("&"); } out->write("\n"); writeAccessorName(out, member, unsafe); - if (memberOwner(member)->type == Object::Pod) { - out->write("("); - out->write(capitalize(local::typeName(memberOwner(member)))); - out->write("*"); - } else { - out->write("(Thread* t UNUSED, object"); - } + out->write("(Thread* t UNUSED, object"); out->write(" o"); if (member->type != Object::Scalar) { out->write(", unsigned i"); @@ -1537,41 +1490,22 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) out->write("*"); } else { out->write(typeName); - if (member->type != Object::Scalar and memberTypeObject(member)) { - out->write("*"); - } else { - out->write("&"); - } + out->write("&"); } out->write(">(reinterpret_cast(o)"); - if (endsWith("[0]", typeName) - or (member->type != Object::Scalar - and memberTypeObject(member))) - { - out->write(" + "); - } else { - out->write("["); - } + out->write("["); out->write(capitalize(local::typeName(memberOwner(member)))); out->write(capitalize(memberName(member))); if (member->type != Object::Scalar) { out->write(" + (i * "); - unsigned elementSize = (memberTypeObject(member) ? - typeSize(memberTypeObject(member)) : - sizeOf(memberTypeName(member), 0)); + unsigned elementSize = sizeOf(memberTypeName(member)); out->write(elementSize); out->write(")"); } - if (not endsWith("[0]", typeName) - and (member->type == Object::Scalar - or memberTypeObject(member) == 0)) - { - out->write("]"); - } - out->write(");\n}\n\n"); + out->write("]);\n}\n\n"); } Object* @@ -1615,39 +1549,13 @@ typeOffset(Object* type) return typeOffset(0, type); } -void -writePods(Output* out, Object* declarations) -{ - for (Object* p = declarations; p; p = cdr(p)) { - Object* o = car(p); - switch (o->type) { - case Object::Pod: { - out->write("const unsigned "); - out->write(capitalize(typeName(o))); - out->write("Size = "); - out->write(typeSize(o)); - out->write(";\n\n"); - - out->write("struct "); - out->write(capitalize(typeName(o))); - out->write(" { uint8_t body["); - out->write(capitalize(typeName(o))); - out->write("Size]; };\n\n"); - } break; - - default: break; - } - } -} - void writeAccessors(Output* out, Object* declarations) { for (Object* p = declarations; p; p = cdr(p)) { Object* o = car(p); switch (o->type) { - case Object::Type: - case Object::Pod: { + case Object::Type: { Object* offset = typeOffset (o, o->type == Object::Type ? typeSuper(o) : 0); for (MemberIterator it(o, true); it.hasMore();) { @@ -2031,15 +1939,6 @@ typeObjectMask(Object* type) case Object::Array: { if (memberGC(m)) { set(&mask, offset); - } else if (memberTypeObject(m) - and memberTypeObject(m)->type == Object::Pod) - { - for (MemberIterator it(memberTypeObject(m)); it.hasMore();) { - Object* m = it.next(); - if (memberGC(m)) { - set(&mask, offset + (it.offset() / BytesPerWord)); - } - } } } break; @@ -2207,13 +2106,73 @@ writeNameInitializations(Output* out, Object* declarations) } } +void +writeMap(Output* out, Object* type) +{ + for (MemberIterator it(type); it.hasMore();) { + Object* m = it.next(); + + switch (m->type) { + case Object::Scalar: { + out->write("Type_"); + out->write(memberTypeEnumName(m)); + } break; + + case Object::Array: { + out->write("Type_array, "); + out->write("Type_"); + out->write(memberTypeEnumName(m)); + } break; + + default: UNREACHABLE; + } + + out->write(", "); + } + + out->write("Type_none"); +} + +void +writeMaps(Output* out, Object* declarations) +{ + unsigned count = 0; + for (Object* p = declarations; p; p = cdr(p)) { + if (car(p)->type == Object::Type) { + ++ count; + } + } + + out->write("Type types[]["); + out->write(count); + out->write("] = {\n"); + bool wrote = false; + for (Object* p = declarations; p; p = cdr(p)) { + Object* o = car(p); + if (o->type == Object::Type) { + if (wrote) { + out->write(",\n"); + } else { + wrote = true; + } + + out->write("// "); + out->write(typeName(o)); + out->write("\n{ "); + writeMap(out, o); + out->write(" }"); + } + } + out->write("\n};"); +} + void usageAndExit(const char* command) { fprintf(stderr, "usage: %s " "{enums,declarations,constructors,initializations," - "java-initializations,name-initializations}\n", + "java-initializations,name-initializations,maps}\n", command); exit(-1); } @@ -2243,7 +2202,8 @@ main(int ac, char** av) or local::equal(av[4], "constructors") or local::equal(av[4], "initializations") or local::equal(av[4], "java-initializations") - or local::equal(av[4], "name-initializations"))) + or local::equal(av[4], "name-initializations") + or local::equal(av[4], "maps"))) { local::usageAndExit(av[0]); } @@ -2301,7 +2261,6 @@ main(int ac, char** av) out.Output::write(local::typeCount(declarations)); out.write(";\n\n"); - local::writePods(&out, declarations); local::writeAccessors(&out, declarations); local::writeSizes(&out, declarations); local::writeInitializerDeclarations(&out, declarations); @@ -2315,6 +2274,8 @@ main(int ac, char** av) local::writeJavaInitializations(&out, declarations); } else if (local::equal(av[4], "name-initializations")) { local::writeNameInitializations(&out, declarations); + } else if (local::equal(av[4], "maps")) { + local::writeMaps(&out, declarations); } return 0; diff --git a/src/types.def b/src/types.def index 2178c3a7fa..c95ed03a0a 100644 --- a/src/types.def +++ b/src/types.def @@ -64,23 +64,13 @@ (type region (void* region) - (unsigned position)) - -(pod exceptionHandler - (uint16_t start) - (uint16_t end) - (uint16_t ip) - (uint16_t catchType)) + (uint32_t position)) (type exceptionHandlerTable - (array exceptionHandler body)) - -(pod lineNumber - (uint32_t ip) - (uint32_t line)) + (array uint64_t body)) (type lineNumberTable - (array lineNumber body)) + (array uint64_t body)) (type code (object pool) @@ -126,7 +116,7 @@ (type traceElement (object method) - (int ip)) + (int32_t ip)) (type treeNode (object value) @@ -155,7 +145,7 @@ (void* waitTail) (object acquireHead) (object acquireTail) - (unsigned depth)) + (uint32_t depth)) (type monitorNode (void* value) diff --git a/src/x86.cpp b/src/x86.cpp index 670c5482d3..5a90ede640 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -9,6 +9,7 @@ details. */ #include "assembler.h" +#include "target.h" #include "vector.h" #define CAST1(x) reinterpret_cast(x) @@ -60,17 +61,17 @@ enum { }; const unsigned GeneralRegisterMask -= BytesPerWord == 4 ? 0x000000ff : 0x0000ffff; += TargetBytesPerWord == 4 ? 0x000000ff : 0x0000ffff; const unsigned FloatRegisterMask -= BytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; += TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1); const int LongJumpRegister = r10; const unsigned StackAlignmentInBytes = 16; -const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord; +const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord; bool isInt8(intptr_t v) @@ -478,7 +479,7 @@ detectFeature(unsigned ecx, unsigned edx); bool useSSE(ArchitectureContext* c) { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { // amd64 implies SSE2 support return true; } else if (c->useNativeFeatures) { @@ -502,7 +503,7 @@ useSSE(ArchitectureContext* c) void maybeRex(Context* c, unsigned size, int a, int index, int base, bool always) { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { uint8_t byte; if (size == 8) { byte = REX_W; @@ -656,7 +657,7 @@ storeLoadBarrier(Context* c) } else { // lock addq $0x0,(%rsp): c->code.append(0xf0); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { c->code.append(0x48); } c->code.append(0x83); @@ -746,7 +747,7 @@ callR(Context*, unsigned, Assembler::Register*); void callC(Context* c, unsigned size UNUSED, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); unconditional(c, 0xe8, a); } @@ -754,9 +755,9 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* a) void longCallC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { Assembler::Register r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); callR(c, size, &r); @@ -768,7 +769,7 @@ longCallC(Context* c, unsigned size, Assembler::Constant* a) void jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); maybeRex(c, 4, a); opcode(c, 0xff, 0xe0 + regCode(a)); @@ -777,7 +778,7 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) void jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); unconditional(c, 0xe9, a); } @@ -785,7 +786,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a) void jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); maybeRex(c, 4, a); opcode(c, 0xff); @@ -795,9 +796,9 @@ jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a) void longJumpC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { Assembler::Register r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); jumpR(c, size, &r); @@ -809,7 +810,7 @@ longJumpC(Context* c, unsigned size, Assembler::Constant* a) void callR(Context* c, unsigned size UNUSED, Assembler::Register* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); // maybeRex.W has no meaning here so we disable it maybeRex(c, 4, a); @@ -819,7 +820,7 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* a) void callM(Context* c, unsigned size UNUSED, Assembler::Memory* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); maybeRex(c, 4, a); opcode(c, 0xff); @@ -836,9 +837,9 @@ alignedCallC(Context* c, unsigned size, Assembler::Constant* a) void alignedLongCallC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { new (c->zone->allocate(sizeof(AlignmentPadding))) AlignmentPadding(c, 2, 8); longCallC(c, size, a); @@ -857,9 +858,9 @@ alignedJumpC(Context* c, unsigned size, Assembler::Constant* a) void alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { new (c->zone->allocate(sizeof(AlignmentPadding))) AlignmentPadding(c, 2, 8); longJumpC(c, size, a); @@ -871,7 +872,7 @@ alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a) void pushR(Context* c, unsigned size, Assembler::Register* a) { - if (BytesPerWord == 4 and size == 8) { + if (TargetBytesPerWord == 4 and size == 8) { Assembler::Register ah(a->high); pushR(c, 4, &ah); @@ -889,7 +890,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, void popR(Context* c, unsigned size, Assembler::Register* a) { - if (BytesPerWord == 4 and size == 8) { + if (TargetBytesPerWord == 4 and size == 8) { Assembler::Register ah(a->high); popR(c, 4, a); @@ -897,7 +898,7 @@ popR(Context* c, unsigned size, Assembler::Register* a) } else { maybeRex(c, 4, a); opcode(c, 0x58 + regCode(a)); - if (BytesPerWord == 8 and size == 4) { + if (TargetBytesPerWord == 8 and size == 4) { moveRR(c, 4, a, 8, a); } } @@ -910,7 +911,7 @@ addCarryCR(Context* c, unsigned size, Assembler::Constant* a, void negateR(Context* c, unsigned size, Assembler::Register* a) { - if (BytesPerWord == 4 and size == 8) { + if (TargetBytesPerWord == 4 and size == 8) { assert(c, a->low == rax and a->high == rdx); ResolvedPromise zeroPromise(0); @@ -940,7 +941,7 @@ void moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a, UNUSED unsigned bSize, Assembler::Register* b, unsigned promiseOffset) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { int64_t v = a->value->value(); ResolvedPromise high((v >> 32) & 0xFFFFFFFF); @@ -954,13 +955,13 @@ moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a, moveCR(c, 4, &al, 4, b); moveCR(c, 4, &ah, 4, &bh); } else { - maybeRex(c, BytesPerWord, b); + maybeRex(c, TargetBytesPerWord, b); opcode(c, 0xb8 + regCode(b)); if (a->value->resolved()) { c->code.appendAddress(a->value->value()); } else { appendImmediateTask - (c, a->value, offset(c), BytesPerWord, promiseOffset); + (c, a->value, offset(c), TargetBytesPerWord, promiseOffset); c->code.appendAddress(static_cast(0)); } } @@ -1008,7 +1009,7 @@ void sseMoveCR(Context* c, unsigned aSize, Assembler::Constant* a, unsigned bSize, Assembler::Register* b) { - assert(c, aSize <= BytesPerWord); + assert(c, aSize <= TargetBytesPerWord); Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR2(c, aSize, a, aSize, &tmp, 0); sseMoveRR(c, aSize, &tmp, bSize, b); @@ -1031,7 +1032,7 @@ swapRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Register* b) { assert(c, aSize == bSize); - assert(c, aSize == BytesPerWord); + assert(c, aSize == TargetBytesPerWord); alwaysRex(c, aSize, a, b); opcode(c, 0x87); @@ -1047,7 +1048,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, return; } - if (BytesPerWord == 4 and aSize == 8 and bSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8 and bSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1065,11 +1066,11 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, } else { switch (aSize) { case 1: - if (BytesPerWord == 4 and a->low > rbx) { + if (TargetBytesPerWord == 4 and a->low > rbx) { assert(c, b->low <= rbx); - moveRR(c, BytesPerWord, a, BytesPerWord, b); - moveRR(c, 1, b, BytesPerWord, b); + moveRR(c, TargetBytesPerWord, a, TargetBytesPerWord, b); + moveRR(c, 1, b, TargetBytesPerWord, b); } else { alwaysRex(c, aSize, b, a); opcode(c, 0x0f, 0xbe); @@ -1085,7 +1086,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, case 4: if (bSize == 8) { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { alwaysRex(c, bSize, b, a); opcode(c, 0x63); modrm(c, 0xc0, a, b); @@ -1125,7 +1126,7 @@ sseMoveMR(Context* c, unsigned aSize, Assembler::Memory* a, { assert(c, aSize >= 4); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { opcode(c, 0xf3); opcode(c, 0x0f, 0x7e); modrmSibImm(c, b, a); @@ -1160,7 +1161,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a, break; case 4: - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { maybeRex(c, bSize, b, a); opcode(c, 0x63); modrmSibImm(c, b, a); @@ -1179,7 +1180,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a, break; case 8: - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale); Assembler::Register bh(b->high); @@ -1203,7 +1204,7 @@ sseMoveRM(Context* c, unsigned aSize, Assembler::Register* a, assert(c, aSize >= 4); assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { opcode(c, 0x66); opcode(c, 0x0f, 0xd6); modrmSibImm(c, a, b); @@ -1241,7 +1242,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, break; case 4: - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { maybeRex(c, bSize, a, b); opcode(c, 0x89); modrmSibImm(c, a, b); @@ -1253,7 +1254,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, break; case 8: - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { maybeRex(c, bSize, a, b); opcode(c, 0x89); modrmSibImm(c, a, b); @@ -1274,7 +1275,7 @@ void moveAR(Context* c, unsigned aSize, Assembler::Address* a, unsigned bSize, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or (aSize == 4 and bSize == 4)); + assert(c, TargetBytesPerWord == 8 or (aSize == 4 and bSize == 4)); Assembler::Constant constant(a->address); Assembler::Memory memory(b->low, 0, -1, 0); @@ -1323,7 +1324,7 @@ moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a, break; case 8: { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { if (a->value->resolved() and isInt32(a->value->value())) { maybeRex(c, bSize, b); opcode(c, 0xc7); @@ -1370,7 +1371,7 @@ void moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a, unsigned bSize UNUSED, Assembler::Register* b) { - assert(c, bSize == BytesPerWord); + assert(c, bSize == TargetBytesPerWord); assert(c, aSize == 2); maybeRex(c, bSize, b, a); @@ -1382,7 +1383,7 @@ void addCarryRR(Context* c, unsigned size, Assembler::Register* a, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or size == 4); + assert(c, TargetBytesPerWord == 8 or size == 4); maybeRex(c, size, a, b); opcode(c, 0x11); @@ -1395,7 +1396,7 @@ addRR(Context* c, unsigned aSize, Assembler::Register* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1432,7 +1433,7 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1468,7 +1469,7 @@ void subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or size == 4); + assert(c, TargetBytesPerWord == 8 or size == 4); int64_t v = a->value->value(); if (isInt8(v)) { @@ -1491,7 +1492,7 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1527,7 +1528,7 @@ void subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or size == 4); + assert(c, TargetBytesPerWord == 8 or size == 4); maybeRex(c, size, a, b); opcode(c, 0x19); @@ -1540,7 +1541,7 @@ subtractRR(Context* c, unsigned aSize, Assembler::Register* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1560,7 +1561,7 @@ andRR(Context* c, unsigned aSize, Assembler::Register* a, assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1581,7 +1582,7 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1618,7 +1619,7 @@ orRR(Context* c, unsigned aSize, Assembler::Register* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1639,7 +1640,7 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1675,7 +1676,7 @@ void xorRR(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Register* b) { - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1696,7 +1697,7 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1735,7 +1736,7 @@ multiplyRR(Context* c, unsigned aSize, Assembler::Register* a, assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { assert(c, b->high == rdx); assert(c, b->low != rax); assert(c, a->low != rax); @@ -1870,7 +1871,7 @@ compareRR(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Register* b) { assert(c, aSize == bSize); - assert(c, aSize <= BytesPerWord); + assert(c, aSize <= TargetBytesPerWord); maybeRex(c, aSize, a, b); opcode(c, 0x39); @@ -1882,7 +1883,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a, unsigned bSize, Assembler::Register* b) { assert(c, aSize == bSize); - assert(c, BytesPerWord == 8 or aSize == 4); + assert(c, TargetBytesPerWord == 8 or aSize == 4); if (a->value->resolved() and isInt32(a->value->value())) { int64_t v = a->value->value(); @@ -1907,9 +1908,9 @@ compareRM(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Memory* b) { assert(c, aSize == bSize); - assert(c, BytesPerWord == 8 or aSize == 4); + assert(c, TargetBytesPerWord == 8 or aSize == 4); - if (BytesPerWord == 8 and aSize == 4) { + if (TargetBytesPerWord == 8 and aSize == 4) { moveRR(c, 4, a, 8, a); } maybeRex(c, bSize, a, b); @@ -1922,7 +1923,7 @@ compareCM(Context* c, unsigned aSize, Assembler::Constant* a, unsigned bSize, Assembler::Memory* b) { assert(c, aSize == bSize); - assert(c, BytesPerWord == 8 or aSize == 4); + assert(c, TargetBytesPerWord == 8 or aSize == 4); if (a->value->resolved()) { int64_t v = a->value->value(); @@ -2048,7 +2049,7 @@ branchRR(Context* c, TernaryOperation op, unsigned size, if (isFloatBranch(op)) { compareFloatRR(c, size, a, size, b); branchFloat(c, op, target); - } else if (size > BytesPerWord) { + } else if (size > TargetBytesPerWord) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -2066,7 +2067,7 @@ branchCR(Context* c, TernaryOperation op, unsigned size, { assert(c, not isFloatBranch(op)); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { int64_t v = a->value->value(); ResolvedPromise low(v & ~static_cast(0)); @@ -2090,7 +2091,7 @@ branchRM(Context* c, TernaryOperation op, unsigned size, Assembler::Constant* target) { assert(c, not isFloatBranch(op)); - assert(c, size <= BytesPerWord); + assert(c, size <= TargetBytesPerWord); compareRM(c, size, a, size, b); branch(c, op, target); @@ -2102,7 +2103,7 @@ branchCM(Context* c, TernaryOperation op, unsigned size, Assembler::Constant* target) { assert(c, not isFloatBranch(op)); - assert(c, size <= BytesPerWord); + assert(c, size <= TargetBytesPerWord); compareCM(c, size, a, size, b); branch(c, op, target); @@ -2114,7 +2115,7 @@ multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); Assembler::Register tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); @@ -2182,7 +2183,7 @@ remainderRR(Context* c, unsigned aSize, Assembler::Register* a, opcode(c, 0xf7, 0xf8 + regCode(a)); Assembler::Register dx(rdx); - moveRR(c, BytesPerWord, &dx, BytesPerWord, b); + moveRR(c, TargetBytesPerWord, &dx, TargetBytesPerWord, b); } void @@ -2194,7 +2195,7 @@ doShift(Context* c, UNUSED void (*shift) { int64_t v = a->value->value(); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { c->client->save(rcx); Assembler::Register cx(rcx); @@ -2219,7 +2220,7 @@ shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, { assert(c, a->low == rcx); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { // shld opcode(c, 0x0f, 0xa5); modrm(c, 0xc0, b->high, b->low); @@ -2255,7 +2256,7 @@ shiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, unsigned bSize, Assembler::Register* b) { assert(c, a->low == rcx); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { // shrd opcode(c, 0x0f, 0xad); modrm(c, 0xc0, b->low, b->high); @@ -2295,7 +2296,7 @@ unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, { assert(c, a->low == rcx); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { // shrd opcode(c, 0x0f, 0xad); modrm(c, 0xc0, b->low, b->high); @@ -2556,7 +2557,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, uint8_t* instruction = static_cast(*ip); // skip stack overflow check, if present: - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if (*start == 0x39) { start += 11; } @@ -2571,7 +2572,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, if (UseFramePointer) { // skip preamble - start += (BytesPerWord == 4 ? 3 : 4); + start += (TargetBytesPerWord == 4 ? 3 : 4); if (instruction <= start or *instruction == 0x5d) { *ip = static_cast(*stack)[1]; @@ -2596,13 +2597,13 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, // check for post-non-tail-call stack adjustment of the form "add // $offset,%rsp": - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if ((*instruction == 0x83 or *instruction == 0x81) and instruction[1] == 0xec) { offset -= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2)) - / BytesPerWord; + / TargetBytesPerWord; } } else if (*instruction == 0x48 and (instruction[1] == 0x83 or instruction[1] == 0x81) @@ -2610,7 +2611,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, { offset -= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3)) - / BytesPerWord; + / TargetBytesPerWord; } // todo: check for and handle tail calls @@ -2773,7 +2774,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual int returnHigh() { - return (BytesPerWord == 4 ? rdx : NoRegister); + return (TargetBytesPerWord == 4 ? rdx : NoRegister); } virtual int virtualCallTarget() { @@ -2807,7 +2808,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned frameFootprint(unsigned footprint) { -#ifdef PLATFORM_WINDOWS +#ifdef TARGET_PLATFORM_WINDOWS return max(footprint, StackAlignmentInWords); #else return max(footprint > argumentRegisterCount() ? @@ -2829,18 +2830,18 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned argumentRegisterCount() { -#ifdef PLATFORM_WINDOWS - if (BytesPerWord == 8) return 4; else +#ifdef TARGET_PLATFORM_WINDOWS + if (TargetBytesPerWord == 8) return 4; else #else - if (BytesPerWord == 8) return 6; else + if (TargetBytesPerWord == 8) return 6; else #endif return 0; } virtual int argumentRegister(unsigned index) { - assert(&c, BytesPerWord == 8); + assert(&c, TargetBytesPerWord == 8); switch (index) { -#ifdef PLATFORM_WINDOWS +#ifdef TARGET_PLATFORM_WINDOWS case 0: return rcx; case 1: @@ -2913,7 +2914,7 @@ class MyArchitecture: public Assembler::Architecture { assertAlignment = false; } - if (BytesPerWord == 4 or op == Call or op == Jump) { + if (TargetBytesPerWord == 4 or op == Call or op == Jump) { uint8_t* instruction = static_cast(returnAddress) - 5; assert(&c, ((op == Call or op == LongCall) and *instruction == 0xE8) @@ -2945,8 +2946,9 @@ class MyArchitecture: public Assembler::Architecture { } } - virtual void setConstant(void* dst, uintptr_t constant) { - memcpy(dst, &constant, BytesPerWord); + virtual void setConstant(void* dst, uint64_t constant) { + target_uintptr_t v = TARGET_VW(constant); + memcpy(dst, &v, TargetBytesPerWord); } virtual unsigned alignFrameSize(unsigned sizeInWords) { @@ -3040,7 +3042,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Absolute: - if (aSize <= BytesPerWord) { + if (aSize <= TargetBytesPerWord) { *aTypeMask = (1 << RegisterOperand); *aRegisterMask = (static_cast(1) << rax); } else { @@ -3089,7 +3091,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Float2Int: - if (useSSE(&c) and bSize <= BytesPerWord) { + if (useSSE(&c) and bSize <= TargetBytesPerWord) { *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; @@ -3099,7 +3101,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Int2Float: - if (useSSE(&c) and aSize <= BytesPerWord) { + if (useSSE(&c) and aSize <= TargetBytesPerWord) { *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); @@ -3112,7 +3114,7 @@ class MyArchitecture: public Assembler::Architecture { *aTypeMask = ~0; *aRegisterMask = ~static_cast(0); - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); const uint32_t mask @@ -3188,7 +3190,7 @@ class MyArchitecture: public Assembler::Architecture { *bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); } - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { *bRegisterMask = (static_cast(1) << (rdx + 32)) | (static_cast(1) << rax); @@ -3223,7 +3225,7 @@ class MyArchitecture: public Assembler::Architecture { *tmpRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } else if (dstTypeMask & (1 << RegisterOperand)) { - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size if (dstRegisterMask & FloatRegisterMask) { @@ -3239,7 +3241,7 @@ class MyArchitecture: public Assembler::Architecture { if (dstRegisterMask & FloatRegisterMask) { // can't move directly from constant to FPR *srcTypeMask &= ~(1 << ConstantOperand); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { *tmpTypeMask = 1 << MemoryOperand; } else { *tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); @@ -3290,7 +3292,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Multiply: - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); *aRegisterMask = (static_cast(mask) << 32) | mask; *bRegisterMask = (static_cast(1) << (rdx + 32)) | mask; @@ -3301,7 +3303,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Divide: - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { *aTypeMask = (1 << RegisterOperand); @@ -3311,7 +3313,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Remainder: - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { *aTypeMask = (1 << RegisterOperand); @@ -3404,15 +3406,15 @@ class MyAssembler: public Assembler { Register stack(rsp); Memory stackLimit(rbx, stackLimitOffsetFromThread); Constant handlerConstant(resolved(&c, handler)); - branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit, + branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, &handlerConstant); } virtual void saveFrame(unsigned stackOffset, unsigned) { Register stack(rsp); Memory stackDst(rbx, stackOffset); - apply(Move, BytesPerWord, RegisterOperand, &stack, - BytesPerWord, MemoryOperand, &stackDst); + apply(Move, TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, MemoryOperand, &stackDst); } virtual void pushFrame(unsigned argumentCount, ...) { @@ -3430,7 +3432,7 @@ class MyAssembler: public Assembler { = static_cast(va_arg(a, int)); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*); footprint += ceiling - (RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord); + (RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } va_end(a); @@ -3448,7 +3450,7 @@ class MyAssembler: public Assembler { RegisterOperand, &dst); } else { - Memory dst(rsp, offset * BytesPerWord); + Memory dst(rsp, offset * TargetBytesPerWord); apply(Move, RUNTIME_ARRAY_BODY(arguments)[i].size, RUNTIME_ARRAY_BODY(arguments)[i].type, @@ -3456,7 +3458,8 @@ class MyAssembler: public Assembler { pad(RUNTIME_ARRAY_BODY(arguments)[i].size), MemoryOperand, &dst); - offset += ceiling(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord); + offset += ceiling + (RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } } } @@ -3466,40 +3469,40 @@ class MyAssembler: public Assembler { if (UseFramePointer) { Register base(rbp); - pushR(&c, BytesPerWord, &base); + pushR(&c, TargetBytesPerWord, &base); - apply(Move, BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &base); + apply(Move, TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &base); } - Constant footprintConstant(resolved(&c, footprint * BytesPerWord)); - apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant, - BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &stack); + Constant footprintConstant(resolved(&c, footprint * TargetBytesPerWord)); + apply(Subtract, TargetBytesPerWord, ConstantOperand, &footprintConstant, + TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &stack); } virtual void adjustFrame(unsigned difference) { Register stack(rsp); - Constant differenceConstant(resolved(&c, difference * BytesPerWord)); - apply(Subtract, BytesPerWord, ConstantOperand, &differenceConstant, - BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &stack); + Constant differenceConstant(resolved(&c, difference * TargetBytesPerWord)); + apply(Subtract, TargetBytesPerWord, ConstantOperand, &differenceConstant, + TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &stack); } virtual void popFrame(unsigned frameFootprint) { if (UseFramePointer) { Register base(rbp); Register stack(rsp); - apply(Move, BytesPerWord, RegisterOperand, &base, - BytesPerWord, RegisterOperand, &stack); + apply(Move, TargetBytesPerWord, RegisterOperand, &base, + TargetBytesPerWord, RegisterOperand, &stack); - popR(&c, BytesPerWord, &base); + popR(&c, TargetBytesPerWord, &base); } else { Register stack(rsp); - Constant footprint(resolved(&c, frameFootprint * BytesPerWord)); - apply(Add, BytesPerWord, ConstantOperand, &footprint, - BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &stack); + Constant footprint(resolved(&c, frameFootprint * TargetBytesPerWord)); + apply(Add, TargetBytesPerWord, ConstantOperand, &footprint, + TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &stack); } } @@ -3515,40 +3518,44 @@ class MyAssembler: public Assembler { unsigned baseSize = UseFramePointer ? 1 : 0; Memory returnAddressSrc - (rsp, (frameFootprint + baseSize) * BytesPerWord); - moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp); + (rsp, (frameFootprint + baseSize) * TargetBytesPerWord); + moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, + &tmp); Memory returnAddressDst - (rsp, (frameFootprint - offset + baseSize) * BytesPerWord); - moveRM(&c, BytesPerWord, &tmp, BytesPerWord, &returnAddressDst); + (rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord); + moveRM(&c, TargetBytesPerWord, &tmp, TargetBytesPerWord, + &returnAddressDst); c.client->releaseTemporary(tmp.low); if (UseFramePointer) { - Memory baseSrc(rsp, frameFootprint * BytesPerWord); + Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord); Register base(rbp); - moveMR(&c, BytesPerWord, &baseSrc, BytesPerWord, &base); + moveMR(&c, TargetBytesPerWord, &baseSrc, TargetBytesPerWord, &base); } Register stack(rsp); Constant footprint - (resolved(&c, (frameFootprint - offset + baseSize) * BytesPerWord)); - addCR(&c, BytesPerWord, &footprint, BytesPerWord, &stack); + (resolved + (&c, (frameFootprint - offset + baseSize) * TargetBytesPerWord)); + + addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack); if (returnAddressSurrogate != NoRegister) { assert(&c, offset > 0); Register ras(returnAddressSurrogate); - Memory dst(rsp, offset * BytesPerWord); - moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst); + Memory dst(rsp, offset * TargetBytesPerWord); + moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } if (framePointerSurrogate != NoRegister) { assert(&c, offset > 0); Register fps(framePointerSurrogate); - Memory dst(rsp, (offset - 1) * BytesPerWord); - moveRM(&c, BytesPerWord, &fps, BytesPerWord, &dst); + Memory dst(rsp, (offset - 1) * TargetBytesPerWord); + moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst); } } else { popFrame(frameFootprint); @@ -3568,15 +3575,15 @@ class MyAssembler: public Assembler { if (TailCalls and argumentFootprint > StackAlignmentInWords) { Register returnAddress(rcx); - popR(&c, BytesPerWord, &returnAddress); + popR(&c, TargetBytesPerWord, &returnAddress); Register stack(rsp); Constant adjustment (resolved(&c, (argumentFootprint - StackAlignmentInWords) - * BytesPerWord)); - addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack); + * TargetBytesPerWord)); + addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack); - jumpR(&c, BytesPerWord, &returnAddress); + jumpR(&c, TargetBytesPerWord, &returnAddress); } else { return_(&c); } @@ -3588,13 +3595,13 @@ class MyAssembler: public Assembler { popFrame(frameFootprint); Register returnAddress(rcx); - popR(&c, BytesPerWord, &returnAddress); + popR(&c, TargetBytesPerWord, &returnAddress); Register stack(rsp); Memory stackSrc(rbx, stackOffsetFromThread); - moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &stack); + moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &stack); - jumpR(&c, BytesPerWord, &returnAddress); + jumpR(&c, TargetBytesPerWord, &returnAddress); } virtual void apply(Operation op) { @@ -3624,7 +3631,7 @@ class MyAssembler: public Assembler { { if (isBranch(op)) { assert(&c, aSize == bSize); - assert(&c, cSize == BytesPerWord); + assert(&c, cSize == TargetBytesPerWord); assert(&c, cType == ConstantOperand); arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)]