Merge remote-tracking branch 'origin/master' into android-upgrade

This commit is contained in:
Joel Dice 2014-09-24 10:59:39 -06:00
commit b406e9c2ed
9 changed files with 281 additions and 122 deletions

View File

@ -13,43 +13,131 @@ apply plugin: 'ivy-publish'
apply plugin: 'java'
apply plugin: 'artifactory-publish'
enum SupportedOS implements OperatingSystem {
LINUX, WINDOWS, MACOSX;
public static final SupportedOS CURRENT;
static {
String p = System.properties['os.name']
switch(p.replaceAll(' ', '').toLowerCase()) {
case ~/.*linux.*/: CURRENT = LINUX; break;
case ~/.*darwin.*/: CURRENT = MACOSX; break;
case ~/.*osx.*/: CURRENT = MACOSX; break;
case ~/.*win.*/: CURRENT = WINDOWS; break;
default:
String m = "SupportedOS: unrecognized platform: ${p}"
println(m)
throw new IllegalArgumentException(m)
}
}
public String getName() {
return toString().toLowerCase()
}
public String getDisplayName() {
return getName()
}
public boolean isCurrent() { return this == CURRENT }
public boolean isFreeBSD() { return false }
public boolean isLinux() { return this == LINUX }
public boolean isMacOsX() { return this == MACOSX }
public boolean isSolaris() { return false }
public boolean isWindows() { return this == WINDOWS }
}
public String adjustArch(String arch) {
switch(arch) {
case ~/.*64.*/: return 'x86_64'
default: return 'i386'
}
}
ext {
currentPlatform = SupportedOS.CURRENT.getName()
currentArch = adjustArch(System.properties['os.arch'])
currentPlatformArch = "${currentPlatform}-${currentArch}"
platform = project.hasProperty('platform') ? platform : currentPlatform
arch = project.hasProperty('arch') ? arch : currentArch
platformArch = "${platform}-${arch}"
java_home = System.properties.'java.home'
if(java_home.endsWith("/jre")) {
java_home = java_home.substring(0, java_home.length() - "/jre".length())
}
java_home = java_home
libDir = "${buildDir}/lib"
}
repositories {
ivy {
name "ivyLocal"
url "${System.env.HOME}/.ivy2/local"
layout 'maven'
}
ivy {
name "jcenter"
if(version.contains("SNAPSHOT")) {
url "http://oss.jfrog.org/artifactory/oss-snapshot-local"
} else {
url "http://oss.jfrog.org/artifactory/oss-release-local"
}
layout 'maven'
}
}
configurations {
create('windows-i386')
create('windows-x86_64')
}
dependencies {
'windows-i386' "com.readytalk:win32:1.0.0-SNAPSHOT"
'windows-x86_64' "com.readytalk:win64:1.0.0-SNAPSHOT"
}
model {
platforms {
if(project.hasProperty("platform") && project.hasProperty("arch")) {
create("${platform}-${arch}") {
operatingSystem "${platform}"
architecture "${arch}"
}
} else {
create("linux-x86_64") {
operatingSystem "linux"
architecture "x86_64"
}
create("linux-i386") {
operatingSystem "linux"
architecture "i386"
}
create("windows-x86_64") {
operatingSystem "windows"
architecture "x86_64"
}
create("windows-i386") {
operatingSystem "windows"
architecture "i386"
create(platformArch) {
operatingSystem SupportedOS.valueOf(platform.toUpperCase())
architecture "${arch}"
}
if(platformArch != currentPlatformArch) {
create(currentPlatformArch) {
operatingSystem SupportedOS.CURRENT
architecture "${currentArch}"
}
}
}
tasks {
platforms.each { platform ->
if(platform.operatingSystem.name == "windows") {
def artifactName = platform.architecture.name == "i386" ? 'win32' : 'win64'
task "extract${platform.name}"(type: Copy) {
from {
tarTree(configurations."${platform.name}".find { it.name =~ artifactName })
}
into "${libDir}/tools"
}
}
task "build${platform.name}"(type: Exec) {
executable "make"
args "platform=${platform.operatingSystem.name}",
"arch=${platform.architecture.name}"
environment JAVA_HOME: "/usr/local/java"
if(platform.operatingSystem.name == "windows") {
dependsOn "extract${platform.name}"
args "win32=${libDir}/tools/win32",
"win64=${libDir}/tools/win64"
}
environment JAVA_HOME: java_home
}
assemble {
@ -74,9 +162,6 @@ sourceSets {
java {
srcDir 'classpath'
}
resources {
srcDir 'classpath'
}
}
}
@ -92,29 +177,51 @@ task javadocJar(type: Jar) {
}
}
jar {
baseName "classpath-avian"
}
task install {
dependsOn assemble, publish
}
publishing {
repositories {
ivy {
url "${System.env.HOME}/.ivy2/local"
layout 'maven'
}
add(project.repositories."ivyLocal")
}
publications {
def binSuffix=""
def publishBinSuffix="bin"
ivy(IvyPublication) {
from components.java
artifact(javadocJar)
artifact("vm.pro") {
name "vm"
type "proguard"
extension "pro"
}
module "classpath-avian"
}
create("tools-avian-${currentPlatformArch}", IvyPublication) {
module "tools-avian-${currentPlatformArch}"
def publishBinSuffix = currentPlatform == "windows" ? "exe" : "bin"
def binSuffix = currentPlatform == "windows" ? ".exe" : ""
artifact("${buildDir}/${currentPlatform}-${currentArch}/binaryToObject/binaryToObject") {
name "binaryToObject"
type publishBinSuffix
extension binSuffix
}
}
platforms.each { platform ->
def binSuffix=""
def publishBinSuffix="bin"
create(platform.name, IvyPublication) {
def nativeBuildDir = "${buildDir}/${platform.operatingSystem.name}-${platform.architecture.name}"
@ -123,18 +230,12 @@ publishing {
binSuffix = ".${publishBinSuffix}"
}
module "${project.name}-${platform.name}"
module "runtime-avian-${platform.name}"
artifact("${nativeBuildDir}/avian${binSuffix}") {
name "avian"
type publishBinSuffix
extension publishBinSuffix
}
artifact("${nativeBuildDir}/binaryToObject/binaryToObject") {
name "binaryToObject"
type publishBinSuffix
extension publishBinSuffix
extension binSuffix
}
artifact("${nativeBuildDir}/libavian.a") {
@ -179,5 +280,5 @@ artifactory {
}
task wrapper(type: Wrapper) {
gradleVersion = '2.0'
distributionUrl = 'http://services.gradle.org/distributions/gradle-2.0-bin.zip'
}

View File

@ -43,6 +43,8 @@ public class Classes {
public static native VMClass getVMClass(Object o);
public static native VMClass toVMClass(Class c);
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
throws ClassNotFoundException;
@ -391,10 +393,25 @@ public class Classes {
return new String(array, 0, array.length - 1);
}
private static boolean match(VMClass a, VMClass b) {
// TODO: in theory we should be able to just do an == comparison
// here instead of recursively comparing array element types.
// However, the VM currently can create multiple array classes for
// the same element type. We should fix that so that there's only
// ever one of each per classloader, eliminating the need for a
// recursive comparison. See also the native implementation of
// isAssignableFrom.
if (a.arrayDimensions > 0) {
return match(a.arrayElementClass, b.arrayElementClass);
} else {
return a == b;
}
}
public static boolean match(Class[] a, Class[] b) {
if (a.length == b.length) {
for (int i = 0; i < a.length; ++i) {
if (! a[i].isAssignableFrom(b[i])) {
if (! match(toVMClass(a[i]), toVMClass(b[i]))) {
return false;
}
}

View File

@ -1,4 +1,4 @@
org.gradle.daemon=true
group=com.readytalk
group=com.readytalk.avian
version=1.1.0-SNAPSHOT

View File

@ -1,6 +1,6 @@
#Wed Jul 23 15:29:56 MDT 2014
#Thu Aug 28 14:47:06 MDT 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-2.0-bin.zip

View File

@ -106,6 +106,13 @@ GcField* fieldForOffset(Thread* t, object o, unsigned offset)
} // namespace
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_toVMClass(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<intptr_t>(
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_avian_Classes_initialize(Thread* t, object, uintptr_t* arguments)
{

View File

@ -3493,9 +3493,9 @@ extern "C" AVIAN_EXPORT jboolean JNICALL
return version <= JNI_VERSION_1_6;
}
extern "C" AVIAN_EXPORT jboolean JNICALL EXPORT(JVM_IsNaN)(jdouble)
extern "C" AVIAN_EXPORT jboolean JNICALL EXPORT(JVM_IsNaN)(jdouble v)
{
abort();
return isnan(v);
}
uint64_t jvmFillInStackTrace(Thread* t, uintptr_t* arguments)

View File

@ -62,10 +62,13 @@ const bool DebugCompile = false;
const bool DebugNatives = false;
const bool DebugCallTable = false;
const bool DebugMethodTree = false;
const bool DebugFrameMaps = false;
const bool DebugInstructions = false;
#ifndef AVIAN_AOT_ONLY
const bool DebugFrameMaps = false;
const bool CheckArrayBounds = true;
const unsigned ExecutableAreaSizeInBytes = 30 * 1024 * 1024;
#endif
#ifdef AVIAN_CONTINUATIONS
const bool Continuations = true;
@ -77,8 +80,6 @@ const unsigned MaxNativeCallFootprint = TargetBytesPerWord == 8 ? 4 : 5;
const unsigned InitialZoneCapacityInBytes = 64 * 1024;
const unsigned ExecutableAreaSizeInBytes = 30 * 1024 * 1024;
enum ThunkIndex {
compileMethodIndex,
compileVirtualMethodIndex,
@ -2012,8 +2013,6 @@ unsigned savedTargetIndex(MyThread* t UNUSED, GcMethod* method)
GcCallNode* findCallNode(MyThread* t, void* address);
void insertCallNode(MyThread* t, GcCallNode* node);
void* findExceptionHandler(Thread* t, GcMethod* method, void* ip)
{
if (t->exception) {
@ -2289,10 +2288,6 @@ uintptr_t nativeThunk(MyThread* t);
uintptr_t bootNativeThunk(MyThread* t);
uintptr_t aioobThunk(MyThread* t);
uintptr_t stackOverflowThunk(MyThread* t);
uintptr_t virtualThunk(MyThread* t, unsigned index);
bool unresolved(MyThread* t, uintptr_t methodAddress);
@ -2401,18 +2396,6 @@ void checkMethod(Thread* t, GcMethod* method, bool shouldBeStatic)
}
}
void checkField(Thread* t, GcField* field, bool shouldBeStatic)
{
if (((field->flags() & ACC_STATIC) == 0) == shouldBeStatic) {
throwNew(t,
GcIncompatibleClassChangeError::Type,
"expected %s.%s to be %s",
field->class_()->name()->body().begin(),
field->name()->body().begin(),
shouldBeStatic ? "static" : "non-static");
}
}
int64_t findSpecialMethodFromReference(MyThread* t, GcPair* pair)
{
PROTECT(t, pair);
@ -3018,6 +3001,35 @@ void idleIfNecessary(MyThread* t)
}
}
bool useLongJump(MyThread* t, uintptr_t target)
{
uintptr_t reach = t->arch->maximumImmediateJump();
FixedAllocator* a = codeAllocator(t);
uintptr_t start = reinterpret_cast<uintptr_t>(a->memory.begin());
uintptr_t end = reinterpret_cast<uintptr_t>(a->memory.begin())
+ a->memory.count;
assertT(t, end - start < reach);
return (target > end && (target - start) > reach)
or (target < start && (end - target) > reach);
}
FILE* compileLog = 0;
void logCompile(MyThread* t,
const void* code,
unsigned size,
const char* class_,
const char* name,
const char* spec);
unsigned simpleFrameMapTableSize(MyThread* t, GcMethod* method, GcIntArray* map)
{
int size = frameMapSizeInBits(t, method);
return ceilingDivide(map->length() * size, 32 + size);
}
#ifndef AVIAN_AOT_ONLY
unsigned resultSize(MyThread* t, unsigned code)
{
switch (code) {
@ -3069,19 +3081,6 @@ ir::Value* popField(MyThread* t, Frame* frame, int code)
}
}
bool useLongJump(MyThread* t, uintptr_t target)
{
uintptr_t reach = t->arch->maximumImmediateJump();
FixedAllocator* a = codeAllocator(t);
uintptr_t start = reinterpret_cast<uintptr_t>(a->memory.begin());
uintptr_t end = reinterpret_cast<uintptr_t>(a->memory.begin())
+ a->memory.count;
assertT(t, end - start < reach);
return (target > end && (target - start) > reach)
or (target < start && (end - target) > reach);
}
void compileSafePoint(MyThread* t, Compiler* c, Frame* frame)
{
c->nativeCall(
@ -3878,6 +3877,22 @@ lir::TernaryOperation toCompilerBinaryOp(MyThread* t, unsigned instruction)
}
}
uintptr_t aioobThunk(MyThread* t);
uintptr_t stackOverflowThunk(MyThread* t);
void checkField(Thread* t, GcField* field, bool shouldBeStatic)
{
if (((field->flags() & ACC_STATIC) == 0) == shouldBeStatic) {
throwNew(t,
GcIncompatibleClassChangeError::Type,
"expected %s.%s to be %s",
field->class_()->name()->body().begin(),
field->name()->body().begin(),
shouldBeStatic ? "static" : "non-static");
}
}
void compile(MyThread* t,
Frame* initialFrame,
unsigned initialIp,
@ -6167,15 +6182,6 @@ branch:
goto start;
}
FILE* compileLog = 0;
void logCompile(MyThread* t,
const void* code,
unsigned size,
const char* class_,
const char* name,
const char* spec);
int resolveIpForwards(Context* context, int start, int end)
{
if (start < 0) {
@ -6621,12 +6627,6 @@ int compareTraceElementPointers(const void* va, const void* vb)
}
}
unsigned simpleFrameMapTableSize(MyThread* t, GcMethod* method, GcIntArray* map)
{
int size = frameMapSizeInBits(t, method);
return ceilingDivide(map->length() * size, 32 + size);
}
uint8_t* finish(MyThread* t,
FixedAllocator* allocator,
avian::codegen::Assembler* a,
@ -6754,6 +6754,8 @@ GcIntArray* makeSimpleFrameMapTable(MyThread* t,
return table;
}
void insertCallNode(MyThread* t, GcCallNode* node);
void finish(MyThread* t, FixedAllocator* allocator, Context* context)
{
avian::codegen::Compiler* c = context->compiler;
@ -6919,9 +6921,7 @@ void finish(MyThread* t, FixedAllocator* allocator, Context* context)
"<clinit>") == 0) {
trap();
}
#if !defined(AVIAN_AOT_ONLY)
syncInstructionCache(start, codeSize);
#endif
}
void compile(MyThread* t, Context* context)
@ -7063,6 +7063,7 @@ void compile(MyThread* t, Context* context)
}
free(stackMap);
}
#endif // not AVIAN_AOT_ONLY
void updateCall(MyThread* t,
avian::codegen::lir::UnaryOperation op,
@ -8249,7 +8250,9 @@ class MyProcessor;
MyProcessor* processor(MyThread* t);
#ifndef AVIAN_AOT_ONLY
void compileThunks(MyThread* t, FixedAllocator* allocator);
#endif
class CompilationHandlerList {
public:
@ -8794,7 +8797,7 @@ class MyProcessor : public Processor {
virtual void dispose()
{
if (codeAllocator.memory.begin()) {
#if !defined(AVIAN_AOT_ONLY)
#ifndef AVIAN_AOT_ONLY
Memory::free(codeAllocator.memory);
#endif
}
@ -8973,7 +8976,7 @@ class MyProcessor : public Processor {
virtual void boot(Thread* t, BootImage* image, uint8_t* code)
{
#if !defined(AVIAN_AOT_ONLY)
#ifndef AVIAN_AOT_ONLY
if (codeAllocator.memory.begin() == 0) {
codeAllocator.memory = Memory::allocate(ExecutableAreaSizeInBytes,
Memory::ReadWriteExecute);
@ -9370,14 +9373,6 @@ GcArray* insertCallNode(MyThread* t,
return table;
}
void insertCallNode(MyThread* t, GcCallNode* node)
{
GcArray* newArray = insertCallNode(
t, compileRoots(t)->callTable(), &(processor(t)->callTableSize), node);
// sequence point, for gc (don't recombine statements)
compileRoots(t)->setCallTable(t, newArray);
}
GcHashMap* makeClassMap(Thread* t,
unsigned* table,
unsigned count,
@ -9764,6 +9759,15 @@ intptr_t getThunk(MyThread* t, Thunk thunk)
+ (thunk * p->thunks.table.length));
}
#ifndef AVIAN_AOT_ONLY
void insertCallNode(MyThread* t, GcCallNode* node)
{
GcArray* newArray = insertCallNode(
t, compileRoots(t)->callTable(), &(processor(t)->callTableSize), node);
// sequence point, for gc (don't recombine statements)
compileRoots(t)->setCallTable(t, newArray);
}
BootImage::Thunk thunkToThunk(const MyProcessor::Thunk& thunk, uint8_t* base)
{
return BootImage::Thunk(
@ -10000,6 +10004,17 @@ void compileThunks(MyThread* t, FixedAllocator* allocator)
}
}
uintptr_t aioobThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->thunks.aioob.start);
}
uintptr_t stackOverflowThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->thunks.stackOverflow.start);
}
#endif // not AVIAN_AOT_ONLY
MyProcessor* processor(MyThread* t)
{
return static_cast<MyProcessor*>(t->m->processor);
@ -10030,16 +10045,6 @@ uintptr_t bootNativeThunk(MyThread* t)
return reinterpret_cast<uintptr_t>(processor(t)->bootThunks.native.start);
}
uintptr_t aioobThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->thunks.aioob.start);
}
uintptr_t stackOverflowThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->thunks.stackOverflow.start);
}
bool unresolved(MyThread* t, uintptr_t methodAddress)
{
return methodAddress == defaultThunk(t)
@ -10119,7 +10124,7 @@ uintptr_t virtualThunk(MyThread* t, unsigned index)
}
void compile(MyThread* t,
FixedAllocator* allocator,
FixedAllocator* allocator UNUSED,
BootContext* bootContext,
GcMethod* method)
{
@ -10135,6 +10140,10 @@ void compile(MyThread* t,
assertT(t, (method->flags() & ACC_NATIVE) == 0);
#ifdef AVIAN_AOT_ONLY
abort(t);
#else
// We must avoid acquiring any locks until after the first pass of
// compilation, since this pass may trigger classloading operations
// involving application classloaders and thus the potential for
@ -10227,6 +10236,7 @@ void compile(MyThread* t,
method,
compileRoots(t)->methodTreeSentinal(),
compareIpToMethodBounds);
#endif // not AVIAN_AOT_ONLY
}
GcCompileRoots* compileRoots(Thread* t)

View File

@ -615,6 +615,7 @@ class BuiltinElement : public JarElement {
const char* name,
const char* libraryName)
: JarElement(s, allocator, name, false),
library(0),
libraryName(libraryName ? copy(allocator, libraryName) : 0)
{
}
@ -657,6 +658,8 @@ class BuiltinElement : public JarElement {
} else if (DebugFind) {
fprintf(stderr, "unable to find %s in %s\n", symbolName, libraryName);
}
} else if (DebugFind) {
fprintf(stderr, "unable to load %s\n", libraryName);
}
}
}
@ -673,7 +676,9 @@ class BuiltinElement : public JarElement {
virtual void dispose()
{
library->disposeAll();
if (library) {
library->disposeAll();
}
if (libraryName) {
allocator->free(libraryName, strlen(libraryName) + 1);
}

View File

@ -260,6 +260,15 @@ public class Reflection {
.getEnclosingMethod().equals
(Reflection.class.getMethod
("main", new Class[] { String[].class })));
Slithy.class.getMethod("tove", Gybe.class);
try {
Slithy.class.getMethod("tove", Bandersnatch.class);
expect(false);
} catch (NoSuchMethodException e) {
// cool
}
}
protected static class Baz {
@ -267,6 +276,16 @@ public class Reflection {
}
}
class Bandersnatch { }
class Gybe extends Bandersnatch { }
class Slithy {
public static void tove(Gybe gybe) {
// ignore
}
}
class Foo {
static {
if (true) throw new MyException();