This commit is contained in:
Valerie Peng 2019-07-25 21:51:13 +00:00
commit ded94368d1
170 changed files with 3525 additions and 2243 deletions

View File

@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -74,7 +74,7 @@ public class TreeDemo extends DemoModule {
public JScrollPane createTree() {
DefaultMutableTreeNode top = new DefaultMutableTreeNode(getString("TreeDemo.music"));
DefaultMutableTreeNode catagory = null ;
DefaultMutableTreeNode category = null;
DefaultMutableTreeNode artist = null;
DefaultMutableTreeNode record = null;
@ -94,12 +94,12 @@ public class TreeDemo extends DemoModule {
char linetype = line.charAt(0);
switch(linetype) {
case 'C':
catagory = new DefaultMutableTreeNode(line.substring(2));
top.add(catagory);
category = new DefaultMutableTreeNode(line.substring(2));
top.add(category);
break;
case 'A':
if(catagory != null) {
catagory.add(artist = new DefaultMutableTreeNode(line.substring(2)));
if(category != null) {
category.add(artist = new DefaultMutableTreeNode(line.substring(2)));
}
break;
case 'R':

View File

@ -8,7 +8,7 @@
# A = Artist / Composer #
# R = Record / Style #
# S = Song Name / Composition #
# C = Catagory #
# C = Category #
# #
################################################################################
C Classical
@ -195,49 +195,49 @@ C Rock
A The Beatles
R A Hard Day's Night
S A Hard Day's Night
S I Should Have Known Better
S If I Fell
S I'm Happy Just To Dance With You
S And I Love Her
S Tell Me Why
S Can't Buy Me Love
S Any Time At All
S I'll Cry Instead
S Things We Said Today
S When I Get Home
S You Can't Do That
S I Should Have Known Better
S If I Fell
S I'm Happy Just To Dance With You
S And I Love Her
S Tell Me Why
S Can't Buy Me Love
S Any Time At All
S I'll Cry Instead
S Things We Said Today
S When I Get Home
S You Can't Do That
R Beatles For Sale
S No Reply
S I'm a Loser
S Baby's In Black
S Rock And Roll Music
S I'll Follow the Sun
S Mr. Moonlight
S Kansas City/Hey Hey Hey Hey
S Eight Days a Week
S Words Of Love
S Honey Don't
S Every Little Thing
S I Don't Want To Spoil the Party
S What You're Doing
S Everybody's Trying To Be My Baby
S No Reply
S I'm a Loser
S Baby's In Black
S Rock And Roll Music
S I'll Follow the Sun
S Mr. Moonlight
S Kansas City/Hey Hey Hey Hey
S Eight Days a Week
S Words Of Love
S Honey Don't
S Every Little Thing
S I Don't Want To Spoil the Party
S What You're Doing
S Everybody's Trying To Be My Baby
R Help!
S Help!
S The Night Before
S You've Got To Hide Your Love Away
S I Need You
S Another Girl
S You're Going To Lose That Girl
S Ticket To Ride
S Act Naturally
S It's Only Love
S You Like Me Too Much
S Tell Me What You See
S I've Just Seen a Face
S Yesterday
S Dizzy Miss Lizzie
S Help!
S The Night Before
S You've Got To Hide Your Love Away
S I Need You
S Another Girl
S You're Going To Lose That Girl
S Ticket To Ride
S Act Naturally
S It's Only Love
S You Like Me Too Much
S Tell Me What You See
S I've Just Seen a Face
S Yesterday
S Dizzy Miss Lizzie
R Rubber Soul
S Drive My Car
S Drive My Car
S Norwegian Wood
S You Won't See Me
S Nowhere Man
@ -245,27 +245,27 @@ S Think For Yourself
S The Word
S Michelle
S What Goes On?
S Girl
S I'm Looking Through You
S In My Life
S Wait
S If I Needed Someone
S Run For Your Life
S Girl
S I'm Looking Through You
S In My Life
S Wait
S If I Needed Someone
S Run For Your Life
R Revolver
S Taxman
S Rigby
S I'm Only Sleeping
S For You To
S Here There And Everywhere
S Taxman
S Rigby
S I'm Only Sleeping
S For You To
S Here There And Everywhere
S Yellow Submarine
S She Said She Said
S Good Day Sunshine
S And Your Bird Can Sing
S For No One
S Doctor Robert
S I Want To Tell You
S Got To Get You Into My Life
S Tomorrow Never Knows
S She Said She Said
S Good Day Sunshine
S And Your Bird Can Sing
S For No One
S Doctor Robert
S I Want To Tell You
S Got To Get You Into My Life
S Tomorrow Never Knows
R Sgt. Pepper's Lonely Hearts Club Band
S Sgt. Pepper's Lonely Hearts Club Band
S With a Little Help From My Friends
@ -554,35 +554,35 @@ S Leaving Science
S What A Life
A Komeda
R Plan 714 Till
S Fuego De La Vida
S Herbamore
S Som I Fjol
S Fuego De La Vida
S Herbamore
S Som I Fjol
S En Spricka I Taket
R Genius Of
S More Is More
S Fire
S Rocket Plane (Music On The Moon)
S Boogie Woogie/Rock 'N' Roll
S Disko
S Top Star
S Light O' My Life
S If
S Frolic
S In Orbit
S Arbogast
S More Is More
S Fire
S Rocket Plane (Music On The Moon)
S Boogie Woogie/Rock 'N' Roll
S Disko
S Top Star
S Light O' My Life
S If
S Frolic
S In Orbit
S Arbogast
S New New No
R What Makes It Go
S Binario
S It's Alright, Baby
S Curious
S Cul de Sac
S Living Things
S Flabbergast
S Campfire
S Happyment
S Our Hospitality
S Focus
S A Simple Formality
S Binario
S It's Alright, Baby
S Curious
S Cul de Sac
S Living Things
S Flabbergast
S Campfire
S Happyment
S Our Hospitality
S Focus
S A Simple Formality
A Steve Miller Band
R Circle Of Love
S Heart Like A Wheel

View File

@ -2040,17 +2040,6 @@ void MacroAssembler::clinit_barrier(Register klass, Register thread, Label* L_fa
bind(L_fallthrough);
}
void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
Register temp_reg,
Label& wrong_method_type) {
assert_different_registers(mtype_reg, mh_reg, temp_reg);
// Compare method type against that of the receiver.
load_heap_oop(temp_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg), mh_reg,
noreg, noreg, false, IS_NOT_NULL);
cmpd(CCR0, temp_reg, mtype_reg);
bne(CCR0, wrong_method_type);
}
RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot,
Register temp_reg,
int extra_slot_offset) {

View File

@ -565,8 +565,6 @@ class MacroAssembler: public Assembler {
Label* L_slow_path = NULL);
// Method handle support (JSR 292).
void check_method_handle_type(Register mtype_reg, Register mh_reg, Register temp_reg, Label& wrong_method_type);
RegisterOrConstant argument_offset(RegisterOrConstant arg_slot, Register temp_reg, int extra_slot_offset = 0);
// Biased locking support

View File

@ -218,85 +218,6 @@ void Label::patch_instructions(MacroAssembler* masm) {
}
}
struct DelayedConstant {
typedef void (*value_fn_t)();
BasicType type;
intptr_t value;
value_fn_t value_fn;
// This limit of 20 is generous for initial uses.
// The limit needs to be large enough to store the field offsets
// into classes which do not have statically fixed layouts.
// (Initial use is for method handle object offsets.)
// Look for uses of "delayed_value" in the source code
// and make sure this number is generous enough to handle all of them.
enum { DC_LIMIT = 20 };
static DelayedConstant delayed_constants[DC_LIMIT];
static DelayedConstant* add(BasicType type, value_fn_t value_fn);
bool match(BasicType t, value_fn_t cfn) {
return type == t && value_fn == cfn;
}
static void update_all();
};
DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT];
// Default C structure initialization rules have the following effect here:
// = { { (BasicType)0, (intptr_t)NULL }, ... };
DelayedConstant* DelayedConstant::add(BasicType type,
DelayedConstant::value_fn_t cfn) {
for (int i = 0; i < DC_LIMIT; i++) {
DelayedConstant* dcon = &delayed_constants[i];
if (dcon->match(type, cfn))
return dcon;
if (dcon->value_fn == NULL) {
dcon->value_fn = cfn;
dcon->type = type;
return dcon;
}
}
// If this assert is hit (in pre-integration testing!) then re-evaluate
// the comment on the definition of DC_LIMIT.
guarantee(false, "too many delayed constants");
return NULL;
}
void DelayedConstant::update_all() {
for (int i = 0; i < DC_LIMIT; i++) {
DelayedConstant* dcon = &delayed_constants[i];
if (dcon->value_fn != NULL && dcon->value == 0) {
typedef int (*int_fn_t)();
typedef address (*address_fn_t)();
switch (dcon->type) {
case T_INT: dcon->value = (intptr_t) ((int_fn_t) dcon->value_fn)(); break;
case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break;
default: break;
}
}
}
}
RegisterOrConstant AbstractAssembler::delayed_value(int(*value_fn)(), Register tmp, int offset) {
intptr_t val = (intptr_t) (*value_fn)();
if (val != 0) return val + offset;
return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
}
RegisterOrConstant AbstractAssembler::delayed_value(address(*value_fn)(), Register tmp, int offset) {
intptr_t val = (intptr_t) (*value_fn)();
if (val != 0) return val + offset;
return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
}
intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) {
DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn);
return &dcon->value;
}
intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) {
DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn);
return &dcon->value;
}
void AbstractAssembler::update_delayed_values() {
DelayedConstant::update_all();
}
void AbstractAssembler::block_comment(const char* comment) {
if (sect() == CodeBuffer::SECT_INSTS) {
code_section()->outer()->block_comment(offset(), comment);

View File

@ -4547,9 +4547,6 @@ void JavaClasses::compute_offsets() {
// BASIC_JAVA_CLASSES_DO_PART1 classes (java_lang_String and java_lang_Class)
// earlier inside SystemDictionary::resolve_well_known_classes()
BASIC_JAVA_CLASSES_DO_PART2(DO_COMPUTE_OFFSETS);
// generated interpreter code wants to know about the offsets we just computed:
AbstractAssembler::update_delayed_values();
}
#if INCLUDE_CDS

View File

@ -79,6 +79,16 @@ private:
inline void do_oop_work(T* p);
};
class ShenandoahEvacUpdateOopStorageRootsClosure : public BasicOopIterateClosure {
private:
ShenandoahHeap* _heap;
Thread* _thread;
public:
inline ShenandoahEvacUpdateOopStorageRootsClosure();
inline void do_oop(oop* p);
inline void do_oop(narrowOop* p);
};
#ifdef ASSERT
class ShenandoahAssertNotForwardedClosure : public OopClosure {
private:

View File

@ -107,6 +107,31 @@ void ShenandoahEvacuateUpdateRootsClosure::do_oop(narrowOop* p) {
do_oop_work(p);
}
ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsClosure() :
_heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
}
void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
oop obj = RawAccess<>::oop_load(p);
if (! CompressedOops::is_null(obj)) {
if (_heap->in_collection_set(obj)) {
shenandoah_assert_marked(p, obj);
oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
if (oopDesc::equals_raw(resolved, obj)) {
resolved = _heap->evacuate_object(obj, _thread);
}
Atomic::cmpxchg(resolved, p, obj);
}
}
}
void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(narrowOop* p) {
ShouldNotReachHere();
}
#ifdef ASSERT
template <class T>
void ShenandoahAssertNotForwardedClosure::do_oop_work(T* p) {

View File

@ -1593,12 +1593,19 @@ public:
void work(uint worker_id) {
ShenandoahEvacOOMScope oom;
ShenandoahEvacuateUpdateRootsClosure cl;
CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
{
// jni_roots and weak_roots are OopStorage backed roots, concurrent iteration
// may race against OopStorage::release() calls.
ShenandoahEvacUpdateOopStorageRootsClosure cl;
_jni_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl);
_weak_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl);
}
_jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
_cld_roots.cld_do(&clds);
_weak_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
{
ShenandoahEvacuateUpdateRootsClosure cl;
CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
_cld_roots.cld_do(&clds);
}
}
};

View File

@ -132,7 +132,7 @@ public class SubSystem {
retval = Long.parseLong(strval);
} catch (NumberFormatException e) {
// For some properties (e.g. memory.limit_in_bytes) we may overflow the range of signed long.
// In this case, return Long.max
// In this case, return Long.MAX_VALUE
BigInteger b = new BigInteger(strval);
if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
return Long.MAX_VALUE;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -91,18 +91,22 @@ char *getMacOSXLocale(int cat) {
if (hyphenPos == NULL || // languageString contains ISO639 only, e.g., "en"
languageString + langStrLen - hyphenPos == 5) { // ISO639-ScriptCode, e.g., "en-Latn"
CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding());
char *underscorePos = strrchr(localeString, '_');
char *region = NULL;
CFLocaleRef cflocale = CFLocaleCopyCurrent();
if (cflocale != NULL) {
CFStringGetCString(CFLocaleGetIdentifier(cflocale),
localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding());
char *underscorePos = strrchr(localeString, '_');
char *region = NULL;
if (underscorePos != NULL) {
region = underscorePos + 1;
}
if (underscorePos != NULL) {
region = underscorePos + 1;
}
if (region != NULL) {
strcat(languageString, "-");
strcat(languageString, region);
if (region != NULL) {
strcat(languageString, "-");
strcat(languageString, region);
}
CFRelease(cflocale);
}
}
@ -112,12 +116,19 @@ char *getMacOSXLocale(int cat) {
default:
{
if (!CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) {
CFLocaleRef cflocale = CFLocaleCopyCurrent();
if (cflocale != NULL) {
if (!CFStringGetCString(CFLocaleGetIdentifier(cflocale),
localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) {
CFRelease(cflocale);
return NULL;
}
retVal = localeString;
CFRelease(cflocale);
} else {
return NULL;
}
retVal = localeString;
}
break;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -317,7 +317,7 @@ class Iocp extends AsynchronousChannelGroupImpl {
myGroupAndInvokeCount.resetInvokeCount();
// wait for I/O completion event
// A error here is fatal (thread will not be replaced)
// An error here is fatal (thread will not be replaced)
replaceMe = false;
try {
getQueuedCompletionStatus(port, ioResult);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -143,7 +143,6 @@ class PendingIoCache {
// simulate the failure of all pending I/O operations.
for (Long ov: pendingIoMap.keySet()) {
PendingFuture<?,?> result = pendingIoMap.get(ov);
assert !result.isDone();
// make I/O port aware of the stale OVERLAPPED structure
Iocp iocp = (Iocp)((Groupable)result.channel()).group();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -228,7 +228,6 @@ public class WindowsAsynchronousFileChannelImpl
@Override
public void run() {
long overlapped = 0L;
boolean pending = false;
try {
begin();
@ -242,7 +241,6 @@ public class WindowsAsynchronousFileChannelImpl
overlapped);
if (n == IOStatus.UNAVAILABLE) {
// I/O is pending
pending = true;
return;
}
// acquired lock immediately
@ -253,9 +251,9 @@ public class WindowsAsynchronousFileChannelImpl
// lock failed or channel closed
removeFromFileLockTable(fli);
result.setFailure(toIOException(x));
} finally {
if (!pending && overlapped != 0L)
if (overlapped != 0L)
ioCache.remove(overlapped);
} finally {
end();
}
@ -448,13 +446,12 @@ public class WindowsAsynchronousFileChannelImpl
} catch (Throwable x) {
// failed to initiate read
result.setFailure(toIOException(x));
if (overlapped != 0L)
ioCache.remove(overlapped);
} finally {
if (!pending) {
if (!pending)
// release resources
if (overlapped != 0L)
ioCache.remove(overlapped);
releaseBufferIfSubstituted();
}
end();
}
@ -628,9 +625,9 @@ public class WindowsAsynchronousFileChannelImpl
result.setFailure(toIOException(x));
// release resources
releaseBufferIfSubstituted();
if (overlapped != 0L)
ioCache.remove(overlapped);
releaseBufferIfSubstituted();
} finally {
end();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -115,7 +115,7 @@ Java_sun_nio_ch_WindowsAsynchronousFileChannelImpl_lockFile(JNIEnv *env, jobject
if (error == ERROR_IO_PENDING) {
return IOS_UNAVAILABLE;
}
JNU_ThrowIOExceptionWithLastError(env, "WriteFile failed");
JNU_ThrowIOExceptionWithLastError(env, "LockFile failed");
return IOS_THROWN;
}
return 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,31 +22,14 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.X11;
import sun.awt.PlatformFont;
import java.awt.GraphicsEnvironment;
public class XFontPeer extends PlatformFont {
final class XFontPeer extends PlatformFont {
/*
* XLFD name for XFontSet.
*/
private String xfsname;
static {
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Initialize JNI field and method IDs for fields that may be
accessed from C.
*/
private static native void initIDs();
public XFontPeer(String name, int style){
XFontPeer(final String name, final int style) {
super(name, style);
}

View File

@ -35,7 +35,6 @@
#include "awt_Font.h"
#include "java_awt_Dimension.h"
#include "multi_font.h"
#include "Disposer.h"
#endif /* !HEADLESS */
#include <jni.h>
@ -436,269 +435,6 @@ awtJNI_FontName(JNIEnv * env, jstring name, char **foundry, char **facename, cha
return 1;
}
struct FontData *
awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg)
{
/* We are going to create at most 4 outstanding local refs in this
* function. */
if ((*env)->EnsureLocalCapacity(env, 4) < 0) {
return NULL;
}
if (!JNU_IsNull(env, font) && awtJNI_IsMultiFont(env, font)) {
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
struct FontData *fdata = NULL;
int32_t i, size;
char *fontsetname = NULL;
char *nativename = NULL;
Boolean doFree = FALSE;
jobjectArray componentFonts = NULL;
jobject peer = NULL;
jobject fontDescriptor = NULL;
jstring fontDescriptorName = NULL;
jstring charsetName = NULL;
fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,
fontIDs.pData);
if (fdata != NULL && fdata->flist != NULL) {
return fdata;
}
size = (*env)->GetIntField(env, font, fontIDs.size);
fdata = (struct FontData *) malloc(sizeof(struct FontData));
peer = (*env)->CallObjectMethod(env, font, fontIDs.getPeer);
componentFonts =
(*env)->GetObjectField(env, peer, platformFontIDs.componentFonts);
/* We no longer need peer */
(*env)->DeleteLocalRef(env, peer);
fdata->charset_num = (*env)->GetArrayLength(env, componentFonts);
fdata->flist = (awtFontList *) malloc(sizeof(awtFontList)
* fdata->charset_num);
fdata->xfont = NULL;
for (i = 0; i < fdata->charset_num; i++) {
/*
* set xlfd name
*/
fontDescriptor = (*env)->GetObjectArrayElement(env, componentFonts, i);
fontDescriptorName =
(*env)->GetObjectField(env, fontDescriptor,
fontDescriptorIDs.nativeName);
if (!JNU_IsNull(env, fontDescriptorName)) {
nativename = (char *) JNU_GetStringPlatformChars(env, fontDescriptorName, NULL);
if (nativename == NULL) {
nativename = "";
doFree = FALSE;
} else {
doFree = TRUE;
}
} else {
nativename = "";
doFree = FALSE;
}
fdata->flist[i].xlfd = malloc(strlen(nativename)
+ strlen(defaultXLFD));
jio_snprintf(fdata->flist[i].xlfd, strlen(nativename) + 10,
nativename, size * 10);
if (nativename != NULL && doFree)
JNU_ReleaseStringPlatformChars(env, fontDescriptorName, (const char *) nativename);
/*
* set charset_name
*/
charsetName =
(*env)->GetObjectField(env, fontDescriptor,
fontDescriptorIDs.charsetName);
fdata->flist[i].charset_name = (char *)
JNU_GetStringPlatformChars(env, charsetName, NULL);
if (fdata->flist[i].charset_name == NULL) {
(*env)->ExceptionClear(env);
JNU_ThrowOutOfMemoryError(env, "Could not create charset name");
return NULL;
}
/* We are done with the objects. */
(*env)->DeleteLocalRef(env, fontDescriptor);
(*env)->DeleteLocalRef(env, fontDescriptorName);
(*env)->DeleteLocalRef(env, charsetName);
/*
* set load & XFontStruct
*/
fdata->flist[i].load = 0;
/*
* This appears to be a bogus check. The actual intent appears
* to be to find out whether this is the "base" font in a set,
* rather than iso8859_1 explicitly. Note that iso8859_15 will
* and must also pass this test.
*/
if (fdata->xfont == NULL &&
strstr(fdata->flist[i].charset_name, "8859_1")) {
fdata->flist[i].xfont =
loadFont(awt_display, fdata->flist[i].xlfd, size * 10);
if (fdata->flist[i].xfont != NULL) {
fdata->flist[i].load = 1;
fdata->xfont = fdata->flist[i].xfont;
fdata->flist[i].index_length = 1;
} else {
/* Free any already allocated storage and fonts */
int j = i;
for (j = 0; j <= i; j++) {
free((void *)fdata->flist[j].xlfd);
JNU_ReleaseStringPlatformChars(env, NULL,
fdata->flist[j].charset_name);
if (fdata->flist[j].load) {
XFreeFont(awt_display, fdata->flist[j].xfont);
}
}
free((void *)fdata->flist);
free((void *)fdata);
if (errmsg != NULL) {
*errmsg = "java/lang" "NullPointerException";
}
(*env)->DeleteLocalRef(env, componentFonts);
return NULL;
}
}
}
(*env)->DeleteLocalRef(env, componentFonts);
/*
* XFontSet will create if the peer of TextField/TextArea
* are used.
*/
fdata->xfs = NULL;
JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata);
Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata));
return fdata;
} else {
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
Display *display = NULL;
struct FontData *fdata = NULL;
char fontSpec[1024];
int32_t height;
int32_t oheight;
int32_t above = 0; /* tries above height */
int32_t below = 0; /* tries below height */
char *foundry = NULL;
char *name = NULL;
char *encoding = NULL;
char *style = NULL;
XFontStruct *xfont = NULL;
jstring family = NULL;
if (JNU_IsNull(env, font)) {
if (errmsg != NULL) {
*errmsg = "java/lang" "NullPointerException";
}
return (struct FontData *) NULL;
}
display = XDISPLAY;
fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,fontIDs.pData);
if (fdata != NULL && fdata->xfont != NULL) {
return fdata;
}
family = (*env)->CallObjectMethod(env, font, fontIDs.getFamily);
if (!awtJNI_FontName(env, family, &foundry, &name, &encoding)) {
if (errmsg != NULL) {
*errmsg = "java/lang" "NullPointerException";
}
(*env)->DeleteLocalRef(env, family);
return (struct FontData *) NULL;
}
style = Style((*env)->GetIntField(env, font, fontIDs.style));
oheight = height = (*env)->GetIntField(env, font, fontIDs.size);
while (1) {
jio_snprintf(fontSpec, sizeof(fontSpec), "-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
foundry,
name,
style,
height,
encoding);
/*fprintf(stderr,"LoadFont: %s\n", fontSpec); */
xfont = XLoadQueryFont(display, fontSpec);
/* XXX: sometimes XLoadQueryFont returns a bogus font structure */
/* with negative ascent. */
if (xfont == NULL || xfont->ascent < 0) {
if (xfont != NULL) {
XFreeFont(display, xfont);
}
if (foundry != anyfoundry) { /* Use ptr comparison here, not strcmp */
/* Try any other foundry before messing with the sizes */
foundry = anyfoundry;
continue;
}
/* We couldn't find the font. We'll try to find an */
/* alternate by searching for heights above and below our */
/* preferred height. We try for 4 heights above and below. */
/* If we still can't find a font we repeat the algorithm */
/* using misc-fixed as the font. If we then fail, then we */
/* give up and signal an error. */
if (above == below) {
above++;
height = oheight + above;
} else {
below++;
if (below > 4) {
if (name != defaultfontname || style != anystyle) {
name = defaultfontname;
foundry = defaultfoundry;
height = oheight;
style = anystyle;
encoding = isolatin1;
above = below = 0;
continue;
} else {
if (errmsg != NULL) {
*errmsg = "java/io/" "FileNotFoundException";
}
(*env)->DeleteLocalRef(env, family);
return (struct FontData *) NULL;
}
}
height = oheight - below;
}
continue;
} else {
fdata = ZALLOC(FontData);
if (fdata == NULL) {
if (errmsg != NULL) {
*errmsg = "java/lang" "OutOfMemoryError";
}
} else {
fdata->xfont = xfont;
JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata);
Disposer_AddRecord(env, font, pDataDisposeMethod,
ptr_to_jlong(fdata));
}
(*env)->DeleteLocalRef(env, family);
return fdata;
}
}
/* not reached */
}
}
/*
* Registered with the 2D disposer to be called after the Font is GC'd.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,11 +34,6 @@ struct FontIDs {
jmethodID getFamily;
};
/* fieldIDs for XFontPeer fields that may be accessed from C */
struct XFontPeerIDs {
jfieldID xfsname;
};
/* fieldIDs for PlatformFont fields that may be accessed from C */
struct PlatformFontIDs {
jfieldID componentFonts;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -119,8 +119,6 @@ struct FontData {
XFontStruct *xfont; /* Latin1 font */
};
extern struct FontData *awtJNI_GetFontData(JNIEnv *env,jobject font, char **errmsg);
extern AwtGraphicsConfigDataPtr getDefaultConfig(int screen);
extern AwtScreenDataPtr getScreenData(int screen);
#endif /* !HEADLESS */

View File

@ -1,393 +0,0 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* These routines are used for display string with multi font.
*/
#ifdef HEADLESS
#error This file should not be included in headless library
#endif
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <jni.h>
#include <jni_util.h>
#include <jvm.h>
#include "awt_Font.h"
#include "awt_p.h"
#include "multi_font.h"
extern XFontStruct *loadFont(Display *, char *, int32_t);
extern struct FontIDs fontIDs;
extern struct PlatformFontIDs platformFontIDs;
extern struct XFontPeerIDs xFontPeerIDs;
/*
* make string with str + string representation of num
* This string is used as tag string of Motif Compound String and FontList.
*/
static void
makeTag(char *str, int32_t num, char *buf)
{
int32_t len = strlen(str);
strcpy(buf, str);
buf[len] = '0' + num % 100;
buf[len + 1] = '\0';
}
static int32_t
awtJNI_GetFontDescriptorNumber(JNIEnv * env
,jobject font
,jobject fd)
{
int32_t i = 0, num;
/* initialize to NULL so that DeleteLocalRef will work. */
jobjectArray componentFonts = NULL;
jobject peer = NULL;
jobject temp = NULL;
jboolean validRet = JNI_FALSE;
if ((*env)->EnsureLocalCapacity(env, 2) < 0 || (*env)->ExceptionCheck(env))
goto done;
peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer);
if (peer == NULL)
goto done;
componentFonts = (jobjectArray)
(*env)->GetObjectField(env,peer,platformFontIDs.componentFonts);
if (componentFonts == NULL)
goto done;
num = (*env)->GetArrayLength(env, componentFonts);
for (i = 0; i < num; i++) {
temp = (*env)->GetObjectArrayElement(env, componentFonts, i);
if ((*env)->IsSameObject(env, fd, temp)) {
validRet = JNI_TRUE;
break;
}
(*env)->DeleteLocalRef(env, temp);
}
done:
(*env)->DeleteLocalRef(env, peer);
(*env)->DeleteLocalRef(env, componentFonts);
if (validRet)
return i;
return 0;
}
jobject
awtJNI_GetFMFont(JNIEnv * env, jobject this)
{
return JNU_CallMethodByName(env, NULL, this, "getFont_NoClientCode",
"()Ljava/awt/Font;").l;
}
jboolean
awtJNI_IsMultiFont(JNIEnv * env, jobject this)
{
jobject peer = NULL;
jobject fontConfig = NULL;
if (this == NULL) {
return JNI_FALSE;
}
if ((*env)->EnsureLocalCapacity(env, 2) < 0) {
return JNI_FALSE;
}
peer = (*env)->CallObjectMethod(env,this,fontIDs.getPeer);
if (peer == NULL) {
return JNI_FALSE;
}
fontConfig = (*env)->GetObjectField(env,peer,platformFontIDs.fontConfig);
(*env)->DeleteLocalRef(env, peer);
if (fontConfig == NULL) {
return JNI_FALSE;
}
(*env)->DeleteLocalRef(env, fontConfig);
return JNI_TRUE;
}
jboolean
awtJNI_IsMultiFontMetrics(JNIEnv * env, jobject this)
{
jobject peer = NULL;
jobject fontConfig = NULL;
jobject font = NULL;
if (JNU_IsNull(env, this)) {
return JNI_FALSE;
}
if ((*env)->EnsureLocalCapacity(env, 3) < 0) {
return JNI_FALSE;
}
font = JNU_CallMethodByName(env, NULL, this, "getFont_NoClientCode",
"()Ljava/awt/Font;").l;
if (JNU_IsNull(env, font) || (*env)->ExceptionCheck(env)) {
return JNI_FALSE;
}
peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer);
(*env)->DeleteLocalRef(env, font);
if (peer == NULL) {
return JNI_FALSE;
}
fontConfig = (*env)->GetObjectField(env,peer,platformFontIDs.fontConfig);
(*env)->DeleteLocalRef(env, peer);
if (fontConfig == NULL) {
return JNI_FALSE;
}
(*env)->DeleteLocalRef(env, fontConfig);
return JNI_TRUE;
}
/* #define FONT_DEBUG 2 */
XFontSet
awtJNI_MakeFontSet(JNIEnv * env, jobject font)
{
jstring xlfd = NULL;
char *xfontset = NULL;
int32_t size;
int32_t length = 0;
char *realxlfd = NULL, *ptr = NULL, *prev = NULL;
char **missing_list = NULL;
int32_t missing_count;
char *def_string = NULL;
XFontSet xfs;
jobject peer = NULL;
jstring xfsname = NULL;
#ifdef FONT_DEBUG
char xx[1024];
#endif
if ((*env)->EnsureLocalCapacity(env, 2) < 0)
return 0;
size = (*env)->GetIntField(env, font, fontIDs.size) * 10;
peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer);
xfsname = (*env)->GetObjectField(env, peer, xFontPeerIDs.xfsname);
if (JNU_IsNull(env, xfsname))
xfontset = "";
else
xfontset = (char *)JNU_GetStringPlatformChars(env, xfsname, NULL);
realxlfd = malloc(strlen(xfontset) + 50);
prev = ptr = xfontset;
while ((ptr = strstr(ptr, "%d"))) {
char save = *(ptr + 2);
*(ptr + 2) = '\0';
jio_snprintf(realxlfd + length, strlen(xfontset) + 50 - length,
prev, size);
length = strlen(realxlfd);
*(ptr + 2) = save;
prev = ptr + 2;
ptr += 2;
}
strcpy(realxlfd + length, prev);
#ifdef FONT_DEBUG
strcpy(xx, realxlfd);
#endif
xfs = XCreateFontSet(awt_display, realxlfd, &missing_list,
&missing_count, &def_string);
#if FONT_DEBUG >= 2
fprintf(stderr, "XCreateFontSet(%s)->0x%x\n", xx, xfs);
#endif
#if FONT_DEBUG
if (missing_count != 0) {
int32_t i;
fprintf(stderr, "XCreateFontSet missing %d fonts:\n", missing_count);
for (i = 0; i < missing_count; ++i) {
fprintf(stderr, "\t\"%s\"\n", missing_list[i]);
}
fprintf(stderr, " requested \"%s\"\n", xx);
#if FONT_DEBUG >= 3
exit(-1);
#endif
}
#endif
free((void *)realxlfd);
if (xfontset && !JNU_IsNull(env, xfsname))
JNU_ReleaseStringPlatformChars(env, xfsname, (const char *) xfontset);
(*env)->DeleteLocalRef(env, peer);
(*env)->DeleteLocalRef(env, xfsname);
return xfs;
}
/*
* get multi font string width with multiple X11 font
*
* ASSUMES: We are not running on a privileged thread
*/
int32_t
awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int offset, int sLength, jobject font)
{
char *err = NULL;
unsigned char *stringData = NULL;
char *offsetStringData = NULL;
int32_t stringCount, i;
int32_t size;
struct FontData *fdata = NULL;
jobject fontDescriptor = NULL;
jbyteArray data = NULL;
int32_t j;
int32_t width = 0;
int32_t length;
XFontStruct *xf = NULL;
jobjectArray dataArray = NULL;
if ((*env)->EnsureLocalCapacity(env, 3) < 0)
return 0;
if (!JNU_IsNull(env, s) && !JNU_IsNull(env, font))
{
jobject peer;
peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer);
dataArray = (*env)->CallObjectMethod(
env,
peer,
platformFontIDs.makeConvertedMultiFontChars,
s, offset, sLength);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
(*env)->DeleteLocalRef(env, peer);
if(dataArray == NULL)
{
return 0;
}
} else {
return 0;
}
fdata = awtJNI_GetFontData(env, font, &err);
if ((*env)->ExceptionCheck(env)) {
(*env)->DeleteLocalRef(env, dataArray);
return 0;
}
stringCount = (*env)->GetArrayLength(env, dataArray);
size = (*env)->GetIntField(env, font, fontIDs.size);
for (i = 0; i < stringCount; i+=2)
{
fontDescriptor = (*env)->GetObjectArrayElement(env, dataArray, i);
data = (*env)->GetObjectArrayElement(env, dataArray, i + 1);
/* Bail if we've finished */
if (fontDescriptor == NULL || data == NULL) {
(*env)->DeleteLocalRef(env, fontDescriptor);
(*env)->DeleteLocalRef(env, data);
break;
}
j = awtJNI_GetFontDescriptorNumber(env, font, fontDescriptor);
if ((*env)->ExceptionCheck(env)) {
(*env)->DeleteLocalRef(env, fontDescriptor);
(*env)->DeleteLocalRef(env, data);
break;
}
if (fdata->flist[j].load == 0) {
xf = loadFont(awt_display,
fdata->flist[j].xlfd, size * 10);
if (xf == NULL) {
(*env)->DeleteLocalRef(env, fontDescriptor);
(*env)->DeleteLocalRef(env, data);
continue;
}
fdata->flist[j].load = 1;
fdata->flist[j].xfont = xf;
if (xf->min_byte1 == 0 && xf->max_byte1 == 0)
fdata->flist[j].index_length = 1;
else
fdata->flist[j].index_length = 2;
}
xf = fdata->flist[j].xfont;
stringData =
(unsigned char *)(*env)->GetPrimitiveArrayCritical(env, data,NULL);
if (stringData == NULL) {
(*env)->DeleteLocalRef(env, fontDescriptor);
(*env)->DeleteLocalRef(env, data);
(*env)->ExceptionClear(env);
JNU_ThrowOutOfMemoryError(env, "Could not get string data");
break;
}
length = (stringData[0] << 24) | (stringData[1] << 16) |
(stringData[2] << 8) | stringData[3];
offsetStringData = (char *)(stringData + (4 * sizeof(char)));
if (fdata->flist[j].index_length == 2) {
width += XTextWidth16(xf, (XChar2b *)offsetStringData, length/2);
} else {
width += XTextWidth(xf, offsetStringData, length);
}
(*env)->ReleasePrimitiveArrayCritical(env, data, stringData, JNI_ABORT);
(*env)->DeleteLocalRef(env, fontDescriptor);
(*env)->DeleteLocalRef(env, data);
}
(*env)->DeleteLocalRef(env, dataArray);
return width;
}

View File

@ -79,16 +79,6 @@ struct MenuComponentIDs menuComponentIDs;
extern Display* awt_init_Display(JNIEnv *env, jobject this);
extern void freeNativeStringArray(char **array, jsize length);
extern char** stringArrayToNative(JNIEnv *env, jobjectArray array, jsize * ret_length);
struct XFontPeerIDs xFontPeerIDs;
JNIEXPORT void JNICALL
Java_sun_awt_X11_XFontPeer_initIDs
(JNIEnv *env, jclass cls)
{
xFontPeerIDs.xfsname =
(*env)->GetFieldID(env, cls, "xfsname", "Ljava/lang/String;");
}
#endif /* !HEADLESS */
/* This function gets called from the static initializer for FileDialog.java

View File

@ -156,9 +156,10 @@ public final class HotSpotGraalManagement implements HotSpotGraalManagementRegis
platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
process();
}
} catch (SecurityException e) {
} catch (SecurityException | UnsatisfiedLinkError | NoClassDefFoundError | UnsupportedOperationException e) {
// Without permission to find or create the MBeanServer,
// we cannot process any Graal mbeans.
// Various other errors can occur in the ManagementFactory (JDK-8076557)
deferred = null;
}
} else {

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.api.directives.test;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.junit.Assert;
import org.junit.Test;
public class ConstantProbablityBranchFoldingTest extends GraalCompilerTest {
public static int branchFoldingSnippet1() {
if (GraalDirectives.injectBranchProbability(0.5, true)) {
return 1;
} else {
return 2;
}
}
public static int branchFoldingSnippet2() {
if (GraalDirectives.injectBranchProbability(0.5, false)) {
return 1;
} else {
return 2;
}
}
@Test
public void testEarlyFolding1() {
test("branchFoldingSnippet1");
}
@Test
public void testEarlyFolding2() {
test("branchFoldingSnippet2");
}
@Override
protected void checkLowTierGraph(StructuredGraph graph) {
NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);
Assert.assertEquals("IfNode count", 0, ifNodes.count());
}
}

View File

@ -75,6 +75,9 @@ public class AArch64BitCountAssemblerTest extends AssemblerTest {
AArch64MacroAssembler masm = new AArch64MacroAssembler(target);
Register dst = registerConfig.getReturnRegister(JavaKind.Int);
Register src = asRegister(cc.getArgument(0));
// Generate a nop first as AArch64 Hotspot requires instruction at nmethod verified
// entry to be a jump or nop. (See https://github.com/oracle/graal/issues/1439)
masm.nop();
RegisterArray registers = registerConfig.filterAllocatableRegisters(AArch64Kind.V64_BYTE, registerConfig.getAllocatableRegisters());
masm.popcnt(size, dst, src, registers.get(registers.size() - 1));
masm.ret(AArch64.lr);

View File

@ -1,12 +1,10 @@
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -22,19 +20,22 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* header for Multi Font String
*/
#ifndef _MULTI_FONT_H_
#define _MULTI_FONT_H_
#ifndef HEADLESS
jboolean awtJNI_IsMultiFont(JNIEnv *env,jobject this);
jboolean awtJNI_IsMultiFontMetrics(JNIEnv *env,jobject this);
XFontSet awtJNI_MakeFontSet(JNIEnv *env,jobject font);
struct FontData *awtJNI_GetFontData(JNIEnv *env,jobject font, char **errmsg);
int32_t awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int32_t offset,
int32_t length, jobject font);
#endif /* !HEADLESS */
#endif /* _MULTI_FONT_H_ */
package org.graalvm.compiler.core.aarch64;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
public interface AArch64LoweringProviderMixin extends LoweringProvider {
@Override
default Integer smallestCompareWidth() {
return 32;
}
@Override
default boolean supportBulkZeroing() {
return false;
}
}

View File

@ -80,9 +80,9 @@ public class AArch64ReadNode extends ReadNode {
*/
public static void replace(ReadNode readNode) {
assert readNode.getUsageCount() == 1;
assert readNode.getUsageAt(0) instanceof ZeroExtendNode || readNode.getUsageAt(0) instanceof SignExtendNode;
assert readNode.usages().first() instanceof ZeroExtendNode || readNode.usages().first() instanceof SignExtendNode;
ValueNode usage = (ValueNode) readNode.getUsageAt(0);
ValueNode usage = (ValueNode) readNode.usages().first();
boolean isSigned = usage instanceof SignExtendNode;
IntegerStamp accessStamp = ((IntegerStamp) readNode.getAccessStamp());

View File

@ -49,7 +49,7 @@ public class AArch64ReadReplacementPhase extends Phase {
if (node instanceof ReadNode) {
ReadNode readNode = (ReadNode) node;
if (readNode.hasExactlyOneUsage()) {
Node usage = readNode.getUsageAt(0);
Node usage = readNode.usages().first();
if (usage instanceof ZeroExtendNode || usage instanceof SignExtendNode) {
AArch64ReadNode.replace(readNode);
}

View File

@ -24,8 +24,10 @@
package org.graalvm.compiler.core.aarch64;
import java.util.List;
import java.util.ListIterator;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.java.DefaultSuitesCreator;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.options.OptionValues;
@ -37,24 +39,33 @@ import org.graalvm.compiler.phases.tiers.LowTierContext;
import org.graalvm.compiler.phases.tiers.Suites;
public class AArch64SuitesCreator extends DefaultSuitesCreator {
private final Class<? extends Phase> insertReadReplacementBefore;
private final List<Class<? extends Phase>> insertReadReplacementBeforePositions;
public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins, Class<? extends Phase> insertReadReplacementBefore) {
public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins, List<Class<? extends Phase>> insertReadReplacementBeforePositions) {
super(compilerConfiguration, plugins);
this.insertReadReplacementBefore = insertReadReplacementBefore;
this.insertReadReplacementBeforePositions = insertReadReplacementBeforePositions;
}
@Override
public Suites createSuites(OptionValues options) {
Suites suites = super.createSuites(options);
ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(insertReadReplacementBefore);
// Put AArch64ReadReplacementPhase right before the SchedulePhase
while (PhaseSuite.findNextPhase(findPhase, insertReadReplacementBefore)) {
// Search for last occurrence of SchedulePhase
ListIterator<BasePhase<? super LowTierContext>> findPhase = null;
for (Class<? extends Phase> phase : insertReadReplacementBeforePositions) {
findPhase = suites.getLowTier().findPhase(phase);
if (findPhase != null) {
// Put AArch64ReadReplacementPhase right before the requested phase
while (PhaseSuite.findNextPhase(findPhase, phase)) {
// Search for last occurrence of SchedulePhase
}
findPhase.previous();
break;
}
}
if (findPhase != null) {
findPhase.add(new AArch64ReadReplacementPhase());
} else {
throw GraalError.shouldNotReachHere("Cannot find phase to insert AArch64ReadReplacementPhase");
}
findPhase.previous();
findPhase.add(new AArch64ReadReplacementPhase());
return suites;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -143,7 +143,7 @@ public class ConstantStackMoveTest extends LIRTest {
}
@Test
public void runByte() throws Throwable {
public void runByte() {
runTest("testByte");
}
@ -157,7 +157,7 @@ public class ConstantStackMoveTest extends LIRTest {
}
@Test
public void runShort() throws Throwable {
public void runShort() {
runTest("testShort");
}
@ -171,7 +171,7 @@ public class ConstantStackMoveTest extends LIRTest {
}
@Test
public void runInt() throws Throwable {
public void runInt() {
runTest("testInt");
}
@ -185,7 +185,7 @@ public class ConstantStackMoveTest extends LIRTest {
}
@Test
public void runLong() throws Throwable {
public void runLong() {
runTest("testLong");
}
@ -199,7 +199,7 @@ public class ConstantStackMoveTest extends LIRTest {
}
@Test
public void runFloat() throws Throwable {
public void runFloat() {
runTest("testFloat");
}
@ -213,7 +213,7 @@ public class ConstantStackMoveTest extends LIRTest {
}
@Test
public void runDouble() throws Throwable {
public void runDouble() {
runTest("testDouble");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -113,7 +113,7 @@ public class StackStoreTest extends LIRTest {
}
@Test
public void run0() throws Throwable {
public void run0() {
runTest("test0", 0xDEADDEAD);
}
@ -122,7 +122,7 @@ public class StackStoreTest extends LIRTest {
}
@Test
public void run1() throws Throwable {
public void run1() {
runTest("test1", 0xDEADDEAD);
}
@ -131,7 +131,7 @@ public class StackStoreTest extends LIRTest {
}
@Test
public void run2() throws Throwable {
public void run2() {
runTest("test2", 0xDEADDEAD);
}

View File

@ -126,6 +126,7 @@ import org.graalvm.compiler.lir.amd64.AMD64Ternary;
import org.graalvm.compiler.lir.amd64.AMD64Unary;
import org.graalvm.compiler.lir.amd64.AMD64ZeroMemoryOp;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryConstFloatOp;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryOp;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
@ -1360,9 +1361,13 @@ public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implemen
}
}
private Variable emitBinary(LIRKind resultKind, VexRVMOp op, Value a, Value b) {
protected Variable emitBinary(LIRKind resultKind, VexRVMOp op, Value a, Value b) {
Variable result = getLIRGen().newVariable(resultKind);
getLIRGen().append(new AVXBinaryOp(op, getRegisterSize(result), result, asAllocatable(a), asAllocatable(b)));
if (b instanceof ConstantValue && (b.getPlatformKind() == AMD64Kind.SINGLE || b.getPlatformKind() == AMD64Kind.DOUBLE)) {
getLIRGen().append(new AVXBinaryConstFloatOp(op, getRegisterSize(result), result, asAllocatable(a), (ConstantValue) b));
} else {
getLIRGen().append(new AVXBinaryOp(op, getRegisterSize(result), result, asAllocatable(a), asAllocatable(b)));
}
return result;
}

View File

@ -47,8 +47,8 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
@ -80,10 +80,10 @@ import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.HashTableSwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.HashTableSwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64LFenceOp;
import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.amd64;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
public interface AMD64LoweringProviderMixin extends LoweringProvider {
@Override
default Integer smallestCompareWidth() {
return 8;
}
@Override
default boolean supportBulkZeroing() {
return true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -50,6 +50,7 @@ import jdk.vm.ci.code.Register;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.PrimitiveConstant;
import jdk.vm.ci.meta.Value;
public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase {
@ -65,6 +66,9 @@ public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase {
switch (c.getJavaKind()) {
case Long:
return NumUtil.isInt(c.asLong());
case Float:
case Double:
return false;
case Object:
return c.isNull();
default:
@ -74,6 +78,12 @@ public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase {
return false;
}
@Override
public boolean mayEmbedConstantLoad(Constant constant) {
// Only consider not inlineable constants here.
return constant instanceof PrimitiveConstant && ((PrimitiveConstant) constant).getJavaKind().isNumericFloat();
}
@Override
public boolean allowConstantToStackMove(Constant constant) {
if (constant instanceof DataPointerConstant) {

View File

@ -289,4 +289,6 @@ public final class GraalOptions {
@Option(help = "If applicable, use bulk zeroing instructions when the zeroing size in bytes exceeds this threshold.", type = OptionType.Expert)
public static final OptionKey<Integer> MinimalBulkZeroingSize = new OptionKey<>(2048);
@Option(help = "Alignment in bytes for loop header blocks.", type = OptionType.Expert)
public static final OptionKey<Integer> LoopHeaderAlignment = new OptionKey<>(16);
}

View File

@ -32,6 +32,8 @@ import static org.graalvm.compiler.core.common.util.TypeConversion.asU2;
import static org.graalvm.compiler.core.common.util.TypeConversion.asU4;
import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import java.nio.ByteBuffer;
import org.graalvm.compiler.core.common.calc.UnsignedMath;
import sun.misc.Unsafe;
@ -103,6 +105,17 @@ public abstract class UnsafeArrayTypeWriter implements TypeWriter {
return result;
}
/** Copies the buffer into the provided ByteBuffer at its current position. */
public final ByteBuffer toByteBuffer(ByteBuffer buffer) {
assert buffer.remaining() <= totalSize;
int initialPos = buffer.position();
for (Chunk cur = firstChunk; cur != null; cur = cur.next) {
buffer.put(cur.data, 0, cur.size);
}
assert buffer.position() - initialPos == totalSize;
return buffer;
}
@Override
public final void putS1(long value) {
long offset = writeOffset(Byte.BYTES);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.sparc;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
public interface SparcLoweringProviderMixin extends LoweringProvider {
@Override
default Integer smallestCompareWidth() {
return 32;
}
@Override
default boolean supportBulkZeroing() {
return false;
}
}

View File

@ -63,4 +63,3 @@ public class ConditionalEliminationPiTest extends ConditionalEliminationTestBase
test("testSnippet1", 1);
}
}

View File

@ -24,6 +24,7 @@
package org.graalvm.compiler.core.test;
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.junit.Test;
public class ConditionalNodeTest extends GraalCompilerTest {
@ -106,4 +107,23 @@ public class ConditionalNodeTest extends GraalCompilerTest {
sink0 = 1;
return Math.min(-1, value);
}
@Test
public void test4() {
test("conditionalTest4", this, 0);
test("conditionalTest4", this, 1);
}
int a;
InvokeKind b;
public static int conditionalTest4(ConditionalNodeTest node, int a) {
if (a == 1) {
node.b = InvokeKind.Virtual;
} else {
node.b = InvokeKind.Special;
}
node.a = a;
return a;
}
}

View File

@ -53,17 +53,18 @@ public class DumpPathTest extends GraalCompilerTest {
String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"};
EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
overrides.put(DebugOptions.DumpPath, dumpDirectoryPath.toString());
overrides.put(DebugOptions.PrintCFG, true);
overrides.put(DebugOptions.PrintGraph, PrintGraphTarget.File);
overrides.put(DebugOptions.PrintCanonicalGraphStrings, true);
overrides.put(DebugOptions.Dump, "*");
// Generate dump files.
test(new OptionValues(getInitialOptions(), overrides), "snippet");
// Check that Ideal files got created, in the right place.
// Check that IGV files got created, in the right place.
checkForFiles(dumpDirectoryPath, extensions);
// Clean up the generated files.
scrubDirectory(dumpDirectoryPath);
removeDirectory(dumpDirectoryPath);
}
/**
@ -92,24 +93,4 @@ public class DumpPathTest extends GraalCompilerTest {
assertTrue(paths[0].equals(paths[i]), paths[0] + " != " + paths[i]);
}
}
/**
* Remove the temporary directory.
*/
private static void scrubDirectory(Path directoryPath) {
try {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
for (Path filePath : stream) {
if (Files.isRegularFile(filePath)) {
Files.delete(filePath);
} else if (Files.isDirectory(filePath)) {
scrubDirectory(filePath);
}
}
}
Files.delete(directoryPath);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

View File

@ -29,7 +29,6 @@ import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
public class FindUniqueConcreteMethodBugTest extends GraalCompilerTest {
@ -44,7 +43,6 @@ public class FindUniqueConcreteMethodBugTest extends GraalCompilerTest {
* {@link PersonImpl#getName()} and {@link Tenant#getName()}).
*/
@Test
@Ignore("fix HotSpotResolvedObjectTypeImpl.findUniqueConcreteMethod")
public void test() throws NoSuchMethodException {
ResolvedJavaMethod ifaceMethod = getMetaAccess().lookupJavaMethod(Person.class.getDeclaredMethod("getName"));
@ -64,9 +62,8 @@ public class FindUniqueConcreteMethodBugTest extends GraalCompilerTest {
// this causes a VM crash as getLabelLength() directly invokes PersonImpl.getName().
test("getLabelLength", tenant);
ResolvedJavaMethod expected = null;
AssumptionResult<ResolvedJavaMethod> actual = getMetaAccess().lookupJavaType(AbstractPerson.class).findUniqueConcreteMethod(ifaceMethod);
Assert.assertEquals(expected, actual.getResult());
Assert.assertNull(String.valueOf(actual), actual);
}

View File

@ -1116,8 +1116,14 @@ public abstract class GraalCompilerTest extends GraalTest {
return graph;
}
@SuppressWarnings("try")
protected void applyFrontEnd(StructuredGraph graph) {
GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), getOptimisticOptimizations(), graph.getProfilingInfo(), createSuites(graph.getOptions()));
DebugContext debug = graph.getDebug();
try (DebugContext.Scope s = debug.scope("FrontEnd", graph)) {
GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), getOptimisticOptimizations(), graph.getProfilingInfo(), createSuites(graph.getOptions()));
} catch (Throwable e) {
throw debug.handle(e);
}
}
protected StructuredGraph lastCompiledGraph;

View File

@ -0,0 +1,491 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class SwitchFoldingTest extends GraalCompilerTest {
private static final String REFERENCE_SNIPPET = "referenceSnippet";
private static final String REFERENCE_SNIPPET_2 = "reference2Snippet";
private static final String REFERENCE_SNIPPET_3 = "reference3Snippet";
private static final String REFERENCE_SNIPPET_4 = "reference4Snippet";
private static final String REFERENCE_SNIPPET_5 = "reference5Snippet";
public static int referenceSnippet(int a) {
switch (a) {
case 0:
return 10;
case 1:
return 5;
case 2:
return 3;
case 3:
return 11;
case 4:
return 14;
case 5:
return 2;
case 6:
return 1;
case 7:
return 0;
case 8:
return 7;
default:
return 6;
}
}
public static int reference2Snippet(int a) {
switch (a) {
case 0:
return 4;
case 1:
case 2:
return 1;
case 3:
return 6;
default:
return 7;
}
}
public static int reference3Snippet(int a) {
switch (a) {
case 0:
return 4;
case 1:
case 2:
case 4:
return 6;
case 6:
case 7:
default:
return 7;
}
}
public static int test1Snippet(int a) {
if (a == 0) {
return 10;
} else if (a == 1) {
return 5;
} else if (a == 2) {
return 3;
} else if (a == 3) {
return 11;
} else if (a == 4) {
return 14;
} else if (a == 5) {
return 2;
} else if (a == 6) {
return 1;
} else if (a == 7) {
return 0;
} else if (a == 8) {
return 7;
} else {
return 6;
}
}
@Test
public void test1() {
test1("test1Snippet");
}
public static int test2Snippet(int a) {
switch (a) {
case 0:
return 10;
case 1:
return 5;
case 2:
return 3;
case 3:
return 11;
case 4:
return 14;
default:
switch (a) {
case 5:
return 2;
case 6:
return 1;
case 7:
return 0;
case 8:
return 7;
default:
return 6;
}
}
}
@Test
public void test2() {
test1("test2Snippet");
}
public static int test3Snippet(int a) {
switch (a) {
case 0:
return 10;
default:
switch (a) {
case 1:
return 5;
default:
switch (a) {
case 2:
return 3;
default:
switch (a) {
case 3:
return 11;
default:
switch (a) {
case 4:
return 14;
default:
switch (a) {
case 5:
return 2;
default:
switch (a) {
case 6:
return 1;
default:
switch (a) {
case 7:
return 0;
default:
switch (a) {
case 8:
return 7;
default:
return 6;
}
}
}
}
}
}
}
}
}
}
@Test
public void test3() {
test1("test3Snippet");
}
public static int test4Snippet(int a) {
switch (a) {
case 0:
return 10;
case 1:
return 5;
case 2:
return 3;
case 3:
return 11;
case 4:
return 14;
case 5:
return 2;
case 6:
return 1;
default:
if (a == 7) {
return 0;
} else if (a == 8) {
return 7;
} else {
return 6;
}
}
}
@Test
public void test4() {
test1("test4Snippet");
}
public static int test5Snippet(int a) {
switch (a) {
case 0:
return 10;
default:
switch (a) {
case 1:
return 5;
default:
switch (a) {
case 2:
return 3;
default:
switch (a) {
case 3:
return 11;
default:
switch (a) {
case 4:
return 14;
default:
switch (a) {
case 5:
return 2;
default:
switch (a) {
case 6:
return 1;
default:
if (a == 7) {
return 0;
} else if (a == 8) {
return 7;
} else {
return 6;
}
}
}
}
}
}
}
}
}
@Test
public void test5() {
test1("test5Snippet");
}
public static int test6Snippet(int a) {
if (a == 0) {
return 10;
} else {
switch (a) {
case 1:
return 5;
default:
if (a == 2) {
return 3;
} else if (a == 3) {
return 11;
} else {
switch (a) {
case 4:
return 14;
case 5:
return 2;
case 6:
return 1;
default:
if (a == 7) {
return 0;
} else if (a == 8) {
return 7;
} else {
return 6;
}
}
}
}
}
}
@Test
public void test6() {
test1("test6Snippet");
}
public static int test7Snippet(int a) {
if (a == 0) {
return 4;
} else {
switch (a) {
case 1:
case 2:
return 1;
case 3:
return 6;
default:
return 7;
}
}
}
@Test
public void test7() {
test2("test7Snippet");
}
public static int test8Snippet(int a) {
switch (a) {
case 0:
return 4;
case 1:
case 2:
case 7:
default:
switch (a) {
case 2:
case 6:
default:
switch (a) {
case 1:
case 2:
case 4:
return 6;
default:
return 7;
}
}
}
}
@Test
public void test8() {
test3("test8Snippet");
}
public static int reference4Snippet(int a) {
switch (a) {
case 0:
return 4;
case 1:
case 2:
case 4:
return 6;
case 6:
return 7;
case 7:
return 7;
default:
return 7;
}
}
public static int test9Snippet(int a) {
switch (a) {
case 0:
return 4;
case 1:
case 2:
case 4:
return 6;
case 6:
case 7:
default:
if (a == 6) {
return 7;
} else if (a == 7) {
return 7;
} else {
return 7;
}
}
}
@Test
public void test9() {
test4("test9Snippet");
}
public static int reference5Snippet(int a) {
switch (a) {
case 0:
return 4;
case 1:
return 1;
case 2:
return 1;
case 3:
return 6;
default:
return 7;
}
}
public static int test10Snippet(int a) {
if (a == 0) {
return 4;
} else {
if (a == 1 || a == 2) {
return 1;
} else {
switch (a) {
case 3:
return 6;
default:
return 7;
}
}
}
}
@Test
public void test10() {
test5("test10Snippet");
}
private void test1(String snippet) {
test(snippet, REFERENCE_SNIPPET);
}
private void test2(String snippet) {
test(snippet, REFERENCE_SNIPPET_2);
}
private void test3(String snippet) {
test(snippet, REFERENCE_SNIPPET_3);
}
private void test4(String snippet) {
test(snippet, REFERENCE_SNIPPET_4);
}
private void test5(String snippet) {
test(snippet, REFERENCE_SNIPPET_5);
}
private void test(String snippet, String ref) {
StructuredGraph graph = parseEager(snippet, StructuredGraph.AllowAssumptions.YES);
DebugContext debug = graph.getDebug();
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
new CanonicalizerPhase().apply(graph, getProviders());
StructuredGraph referenceGraph = parseEager(ref, StructuredGraph.AllowAssumptions.YES);
assertEquals(referenceGraph, graph);
}
}

View File

@ -45,10 +45,10 @@ public abstract class BackendTest extends GraalCompilerTest {
}
@SuppressWarnings("try")
protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) {
protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph, OptimisticOptimizations optimizations) {
DebugContext debug = graph.getDebug();
try (DebugContext.Scope s = debug.scope("FrontEnd")) {
GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, graph.getProfilingInfo(), createSuites(graph.getOptions()));
GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), optimizations, graph.getProfilingInfo(), createSuites(graph.getOptions()));
} catch (Throwable e) {
throw debug.handle(e);
}
@ -57,4 +57,7 @@ public abstract class BackendTest extends GraalCompilerTest {
return lirGen;
}
protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) {
return getLIRGenerationResult(graph, OptimisticOptimizations.NONE);
}
}

View File

@ -302,10 +302,16 @@ public abstract class CompilationWrapper<T> {
}
}
/**
* Calls {@link System#exit(int)} in the runtime embedding the Graal compiler. This will be a
* different runtime than Graal's runtime in the case of libgraal.
*/
protected abstract void exitHostVM(int status);
private void maybeExitVM(ExceptionAction action) {
if (action == ExitVM) {
TTY.println("Exiting VM after retry compilation of " + this);
System.exit(-1);
exitHostVM(-1);
}
}

View File

@ -156,10 +156,6 @@ public class DebugInfoBuilder {
}
assert checkValues(vobjValue.getType(), values, slotKinds);
vobjValue.setValues(values, slotKinds);
if (vobjNode instanceof VirtualBoxingNode) {
GraalServices.markVirtualObjectAsAutoBox(vobjValue);
}
}
virtualObjectsArray = new VirtualObject[virtualObjects.size()];
@ -323,7 +319,8 @@ public class DebugInfoBuilder {
assert obj.entryCount() == 0 || state instanceof VirtualObjectState;
VirtualObject vobject = virtualObjects.get(obj);
if (vobject == null) {
vobject = VirtualObject.get(obj.type(), virtualObjects.size());
boolean isAutoBox = obj instanceof VirtualBoxingNode;
vobject = GraalServices.createVirtualObject(obj.type(), virtualObjects.size(), isAutoBox);
virtualObjects.put(obj, vobject);
pendingVirtualObjects.add(obj);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it

View File

@ -257,7 +257,6 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
* @throws BailoutException if the code installation failed
*/
public InstalledCode createDefaultInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationResult compilationResult) {
System.out.println(compilationResult.getSpeculationLog());
return createInstalledCode(debug, method, compilationResult, null, true);
}

View File

@ -818,22 +818,24 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
private void replaceAtMatchingUsages(Node other, Predicate<Node> filter, Node toBeDeleted) {
if (filter == null) {
fail("filter cannot be null");
throw fail("filter cannot be null");
}
checkReplaceWith(other);
int i = 0;
while (i < this.getUsageCount()) {
int usageCount = this.getUsageCount();
while (i < usageCount) {
Node usage = this.getUsageAt(i);
if (filter.test(usage)) {
replaceAtUsage(other, toBeDeleted, usage);
this.movUsageFromEndTo(i);
usageCount--;
} else {
++i;
}
}
}
public Node getUsageAt(int index) {
private Node getUsageAt(int index) {
if (index == 0) {
return this.usage0;
} else if (index == 1) {
@ -848,14 +850,35 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
replaceAtMatchingUsages(other, usagePredicate, null);
}
private void replaceAtUsagePos(Node other, Node usage, Position pos) {
pos.initialize(usage, other);
maybeNotifyInputChanged(usage);
if (other != null) {
other.addUsage(usage);
}
}
public void replaceAtUsages(InputType type, Node other) {
checkReplaceWith(other);
for (Node usage : usages().snapshot()) {
int i = 0;
int usageCount = this.getUsageCount();
if (usageCount == 0) {
return;
}
usages: while (i < usageCount) {
Node usage = this.getUsageAt(i);
for (Position pos : usage.inputPositions()) {
if (pos.getInputType() == type && pos.get(usage) == this) {
pos.set(usage, other);
replaceAtUsagePos(other, usage, pos);
this.movUsageFromEndTo(i);
usageCount--;
continue usages;
}
}
i++;
}
if (hasNoUsages()) {
maybeNotifyZeroUsages(this);
}
}
@ -913,6 +936,14 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
}
}
public void replaceFirstInput(Node oldInput, Node newInput, InputType type) {
for (Position pos : inputPositions()) {
if (pos.getInputType() == type && pos.get(this) == oldInput) {
pos.set(this, newInput);
}
}
}
public void clearInputs() {
assert assertFalse(isDeleted(), "cannot clear inputs of deleted node");
getNodeClass().unregisterAtInputsAsUsage(this);
@ -1059,6 +1090,8 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
assertFalse(input.isDeleted(), "input was deleted %s", input);
assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph");
assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType());
Class<?> expectedType = pos.getType();
assertTrue(expectedType.isAssignableFrom(input.getClass()), "Invalid input type for %s: expected a %s but was a %s", pos, expectedType, input.getClass());
}
}
return true;

View File

@ -126,7 +126,7 @@ public final class NodeClass<T> extends FieldIntrospection<T> {
field.setAccessible(true);
return (NodeClass<T>) field.get(null);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
throw new RuntimeException(e);
throw new RuntimeException("Could not load Graal NodeClass TYPE field for " + clazz, e);
}
}

View File

@ -127,6 +127,7 @@ public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {
private boolean check(Node node) {
assert node.graph() == graph : String.format("%s is not part of the graph", node);
assert !isNew(node) : "this node was added to the graph after creating the node map : " + node;
assert node.isAlive() : "this node is not alive: " + node;
return true;
}

View File

@ -146,4 +146,12 @@ public final class Position {
public int getIndex() {
return index;
}
public Class<?> getType() {
if (index < edges.getDirectCount()) {
return edges.getType(index);
} else {
return Node.class;
}
}
}

View File

@ -49,6 +49,7 @@ import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.gen.LIRGenerationProvider;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@ -72,12 +73,16 @@ import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.Mark;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotSentinelConstant;
import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig;
@ -85,6 +90,8 @@ import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import sun.misc.Unsafe;
/**
* HotSpot AArch64 specific backend.
*/
@ -126,6 +133,46 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
}
}
@Override
public InstalledCode createInstalledCode(DebugContext debug,
ResolvedJavaMethod method,
CompilationRequest compilationRequest,
CompilationResult compilationResult,
InstalledCode predefinedInstalledCode,
boolean isDefault,
Object[] context) {
boolean isStub = (method == null);
boolean isAOT = compilationResult.isImmutablePIC();
if (!isStub && !isAOT) {
// Non-stub compilation results are installed into HotSpot as nmethods. As AArch64 has
// a constraint that the instruction at nmethod verified entry point should be a nop or
// jump, AArch64HotSpotBackend always generate a nop placeholder before the code body
// for non-AOT compilations. See AArch64HotSpotBackend.emitInvalidatePlaceholder(). This
// assert checks if the nop placeholder is generated at all required places, including
// in manually assembled code in CodeGenTest cases.
assert hasInvalidatePlaceholder(compilationResult);
}
return super.createInstalledCode(debug, method, compilationRequest, compilationResult, predefinedInstalledCode, isDefault, context);
}
private boolean hasInvalidatePlaceholder(CompilationResult compilationResult) {
byte[] targetCode = compilationResult.getTargetCode();
int verifiedEntryOffset = 0;
for (Mark mark : compilationResult.getMarks()) {
Object markId = mark.id;
if (markId instanceof Integer && (int) markId == config.MARKID_VERIFIED_ENTRY) {
// The nmethod verified entry is located at some pc offset.
verifiedEntryOffset = mark.pcOffset;
break;
}
}
Unsafe unsafe = GraalUnsafeAccess.getUnsafe();
int instruction = unsafe.getIntVolatile(targetCode, unsafe.arrayBaseOffset(byte[].class) + verifiedEntryOffset);
AArch64MacroAssembler masm = new AArch64MacroAssembler(getTarget());
masm.nop();
return instruction == masm.getInt(0);
}
private class HotSpotFrameContext implements FrameContext {
final boolean isStub;

View File

@ -29,6 +29,7 @@ import static jdk.vm.ci.aarch64.AArch64.sp;
import static jdk.vm.ci.common.InitTimer.timer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.graalvm.compiler.bytecode.BytecodeProvider;
@ -193,7 +194,7 @@ public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins,
@SuppressWarnings("unused") Replacements replacements) {
AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, SchedulePhase.class);
AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, Arrays.asList(SchedulePhase.class));
Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool()));
return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase);
}

View File

@ -25,6 +25,7 @@
package org.graalvm.compiler.hotspot.aarch64;
import org.graalvm.compiler.core.aarch64.AArch64LoweringProviderMixin;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.graph.Node;
@ -45,7 +46,7 @@ import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
public class AArch64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider {
public class AArch64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider implements AArch64LoweringProviderMixin {
private AArch64IntegerArithmeticSnippets integerArithmeticSnippets;
private AArch64FloatArithmeticSnippets floatArithmeticSnippets;

View File

@ -27,6 +27,7 @@ package org.graalvm.compiler.hotspot.amd64;
import static org.graalvm.compiler.hotspot.HotSpotBackend.Options.GraalArithmeticStubs;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.amd64.AMD64LoweringProviderMixin;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.graph.Node;
@ -53,7 +54,7 @@ import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider {
public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider implements AMD64LoweringProviderMixin {
private AMD64ConvertSnippets.Templates convertSnippets;
private ProbabilisticProfileSnippets.Templates profileSnippets;
@ -135,14 +136,4 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, dispatchNode.getStubCallDescriptor(), dispatchNode.getStubCallArgs()));
graph.replaceFixed(dispatchNode, call);
}
@Override
public Integer smallestCompareWidth() {
return 8;
}
@Override
public boolean supportBulkZeroing() {
return true;
}
}

View File

@ -34,7 +34,7 @@ import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.ValueUtil;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotConstant;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.Value;
@ -58,8 +58,8 @@ final class AMD64HotSpotStrategySwitchOp extends AMD64ControlFlow.StrategySwitch
@Override
protected void emitComparison(Constant c) {
if (c instanceof HotSpotMetaspaceConstant) {
HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) c;
if (c instanceof HotSpotConstant) {
HotSpotConstant meta = (HotSpotConstant) c;
if (meta.isCompressed()) {
crb.recordInlineDataInCode(meta);
masm.cmpl(keyRegister, 0xDEADDEAD);

View File

@ -28,6 +28,7 @@ import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine;
import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -100,7 +101,7 @@ public class BenchmarkCounterOverflowTest extends LIRTest {
}
@Test
public void spawnSubprocess() throws Throwable {
public void spawnSubprocess() throws IOException, InterruptedException {
Assume.assumeFalse("subprocess already spawned -> skip", Boolean.getBoolean(SUBPROCESS_PROPERTY));
List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine());
vmArgs.add("-XX:JVMCICounterSize=1");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -120,7 +120,7 @@ public class ExceedMaxOopMapStackOffset extends LIRTest {
}
@Test
public void runStackObjects() throws Throwable {
public void runStackObjects() {
int max = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig().maxOopMapStackOffset;
if (max == Integer.MAX_VALUE) {
max = 16 * 1024 - 64;

View File

@ -153,7 +153,7 @@ public class MitigateExceedingMaxOopMapStackOffsetTest extends LIRTest {
}
@Test
public void runStackObjects() throws Throwable {
public void runStackObjects() {
int max = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig().maxOopMapStackOffset;
Assume.assumeFalse("no limit on oop map size", max == Integer.MAX_VALUE);
numPrimitiveSlots = (max / 8) * 2;

View File

@ -25,6 +25,7 @@
package org.graalvm.compiler.hotspot.sparc;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.sparc.SparcLoweringProviderMixin;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.meta.DefaultHotSpotLoweringProvider;
@ -36,7 +37,7 @@ import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
public class SPARCHotSpotLoweringProvider extends DefaultHotSpotLoweringProvider {
public class SPARCHotSpotLoweringProvider extends DefaultHotSpotLoweringProvider implements SparcLoweringProviderMixin {
public SPARCHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {

View File

@ -24,85 +24,97 @@
package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPEC;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
public class BoxDeoptimizationTest extends GraalCompilerTest {
private static boolean isJDK13OrLater = JavaVersionUtil.JAVA_SPEC >= 13;
public static void testInteger() {
Object[] values = {42, new Exception()};
private static void checkJDK() {
Assume.assumeTrue(JAVA_SPEC == 8 || JAVA_SPEC >= 13);
}
public static void testIntegerSnippet() {
Object[] values = {42, -42, new Exception()};
GraalDirectives.deoptimize();
Assert.assertSame(values[0], Integer.valueOf(42));
Assert.assertSame(values[1], Integer.valueOf(-42));
}
@Test
public void test1() {
Assume.assumeTrue(isJDK13OrLater);
test("testInteger");
public void testInteger() {
checkJDK();
test("testIntegerSnippet");
}
public static void testLong() {
Object[] values = {42L, new Exception()};
public static void testLongSnippet() {
long highBitsOnly = 2L << 40;
Object[] values = {42L, -42L, highBitsOnly, new Exception()};
GraalDirectives.deoptimize();
Assert.assertSame(values[0], Long.valueOf(42));
Assert.assertSame(values[1], Long.valueOf(-42));
Assert.assertNotSame(values[2], highBitsOnly);
}
@Test
public void test2() {
Assume.assumeTrue(isJDK13OrLater);
test("testLong");
public void testLong() {
checkJDK();
test("testLongSnippet");
}
public static void testChar() {
Object[] values = {'a', new Exception()};
public static void testCharSnippet() {
Object[] values = {'a', 'Z', new Exception()};
GraalDirectives.deoptimize();
Assert.assertSame(values[0], Character.valueOf('a'));
Assert.assertSame(values[1], Character.valueOf('Z'));
}
@Test
public void test3() {
Assume.assumeTrue(isJDK13OrLater);
test("testChar");
public void testChar() {
checkJDK();
test("testCharSnippet");
}
public static void testShort() {
Object[] values = {(short) 42, new Exception()};
public static void testShortSnippet() {
Object[] values = {(short) 42, (short) -42, new Exception()};
GraalDirectives.deoptimize();
Assert.assertSame(values[0], Short.valueOf((short) 42));
Assert.assertSame(values[1], Short.valueOf((short) -42));
}
@Test
public void test4() {
Assume.assumeTrue(isJDK13OrLater);
test("testShort");
public void testShort() {
checkJDK();
test("testShortSnippet");
}
public static void testByte() {
Object[] values = {(byte) 42, new Exception()};
public static void testByteSnippet() {
Object[] values = {(byte) 42, (byte) -42, new Exception()};
GraalDirectives.deoptimize();
Assert.assertSame(values[0], Byte.valueOf((byte) 42));
Assert.assertSame(values[1], Byte.valueOf((byte) -42));
}
@Test
public void test5() {
Assume.assumeTrue(isJDK13OrLater);
test("testByte");
public void testByte() {
checkJDK();
test("testByteSnippet");
}
public static void testBoolean() {
Object[] values = {true, new Exception()};
public static void testBooleanSnippet() {
Object[] values = {true, false, new Exception()};
GraalDirectives.deoptimize();
Assert.assertSame(values[0], Boolean.valueOf(true));
Assert.assertSame(values[1], Boolean.valueOf(false));
}
@Test
public void test6() {
Assume.assumeTrue(isJDK13OrLater);
test("testBoolean");
public void testBoolean() {
checkJDK();
test("testBooleanSnippet");
}
}

View File

@ -24,6 +24,9 @@
package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins.aesDecryptName;
import static org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins.aesEncryptName;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@ -41,6 +44,7 @@ import jdk.internal.vm.compiler.collections.MapCursor;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
@ -501,21 +505,17 @@ public class CheckGraalIntrinsics extends GraalTest {
"java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
}
boolean implNames = HotSpotGraphBuilderPlugins.cbcUsesImplNames(config);
String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
// AES intrinsics
if (!config.useAESIntrinsics) {
if (isJDK9OrHigher()) {
add(ignore,
"com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V",
"com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I");
} else {
add(ignore,
"com/sun/crypto/provider/AESCrypt.decryptBlock([BI[BI)V",
"com/sun/crypto/provider/AESCrypt.encryptBlock([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining.decrypt([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining.encrypt([BII[BI)I");
}
add(ignore,
"com/sun/crypto/provider/AESCrypt." + aesDecryptName + "([BI[BI)V",
"com/sun/crypto/provider/AESCrypt." + aesEncryptName + "([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining." + cbcDecryptName + "([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining." + cbcEncryptName + "([BII[BI)I");
}
// BigInteger intrinsics

View File

@ -29,6 +29,7 @@ import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -209,10 +210,9 @@ public class CompilationWrapperTest extends GraalCompilerTest {
System.out.println(proc);
}
List<Probe> probes = new ArrayList<>(initialProbes);
Probe diagnosticProbe = null;
if (!extraVmArgs.contains("-Dgraal.TruffleCompilationExceptionsAreFatal=true")) {
diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
try {
List<Probe> probes = new ArrayList<>(initialProbes);
Probe diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
probes.add(diagnosticProbe);
probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
@Override
@ -220,22 +220,20 @@ public class CompilationWrapperTest extends GraalCompilerTest {
return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
}
});
}
for (String line : proc.output) {
for (Probe probe : probes) {
if (probe.matches(line)) {
break;
for (String line : proc.output) {
for (Probe probe : probes) {
if (probe.matches(line)) {
break;
}
}
}
}
for (Probe probe : probes) {
String error = probe.test();
if (error != null) {
Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc));
for (Probe probe : probes) {
String error = probe.test();
if (error != null) {
Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc));
}
}
}
if (diagnosticProbe != null) {
String line = diagnosticProbe.lastMatchingLine;
int substringStart = line.indexOf(diagnosticProbe.substring);
int substringLength = diagnosticProbe.substring.length();
@ -263,8 +261,10 @@ public class CompilationWrapperTest extends GraalCompilerTest {
}
} finally {
zip.delete();
dumpPath.delete();
}
} finally {
Path directory = dumpPath.toPath();
removeDirectory(directory);
}
}
}

View File

@ -313,8 +313,8 @@ public class CompressedOopTest extends GraalCompilerTest {
Assert.assertTrue(buffer.length() == 28);
String a = new String("TestTestTestTestTestTestTest");
installedBenchmarkCode.executeVarargs(buffer, a.toCharArray());
Assert.assertTrue(buffer.length() == 56);
Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
Assert.assertEquals(56, buffer.length());
Assert.assertEquals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest", buffer.toString());
}
public static void stringBuilderTest(Object c1, Object c2) {
@ -339,8 +339,8 @@ public class CompressedOopTest extends GraalCompilerTest {
for (int i = 0; i < add.length; i++) {
buffer.append(add[i]);
}
Assert.assertTrue(buffer.length() == 56);
Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
Assert.assertEquals(56, buffer.length());
Assert.assertEquals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest", buffer.toString());
}
@Test
@ -356,8 +356,8 @@ public class CompressedOopTest extends GraalCompilerTest {
char[] dst = new char[buffer.length() * 2];
System.arraycopy(buffer.toString().toCharArray(), 0, dst, 0, buffer.length());
System.arraycopy(a.toCharArray(), 0, dst, buffer.length(), buffer.length());
Assert.assertTrue(dst.length == 56);
Assert.assertTrue(new String(dst).equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
Assert.assertEquals(56, dst.length);
Assert.assertEquals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest", new String(dst));
}
@Test

View File

@ -35,12 +35,11 @@ import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.junit.Assert;
import org.junit.Test;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -91,7 +90,10 @@ public class HotSpotCryptoSubstitutionTest extends HotSpotGraalCompilerTest {
@Test
public void testCipherBlockChainingIntrinsics() throws Exception {
if (compileAndInstall("com.sun.crypto.provider.CipherBlockChaining", HotSpotGraphBuilderPlugins.cbcEncryptName, HotSpotGraphBuilderPlugins.cbcDecryptName)) {
boolean implNames = HotSpotGraphBuilderPlugins.cbcUsesImplNames(runtime().getVMConfig());
String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
if (compileAndInstall("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, cbcDecryptName)) {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding"));
actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding"));

View File

@ -378,12 +378,15 @@ public class HotSpotGraalManagementTest {
MBeanAttributeInfo dumpPath = findAttributeInfo("DumpPath", info);
MBeanAttributeInfo printGraphFile = findAttributeInfo("PrintGraphFile", info);
MBeanAttributeInfo showDumpFiles = findAttributeInfo("ShowDumpFiles", info);
MBeanAttributeInfo methodFilter = findAttributeInfo("MethodFilter", info);
Object originalDumpPath = server.getAttribute(mbeanName, dumpPath.getName());
Object originalPrintGraphFile = server.getAttribute(mbeanName, printGraphFile.getName());
Object originalShowDumpFiles = server.getAttribute(mbeanName, showDumpFiles.getName());
Object originalMethodFilter = server.getAttribute(mbeanName, methodFilter.getName());
final File tmpDir = new File(HotSpotGraalManagementTest.class.getSimpleName() + "_" + System.currentTimeMillis()).getAbsoluteFile();
server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), quoted(tmpDir)));
server.setAttribute(mbeanName, new Attribute(methodFilter.getName(), ""));
// Force output to a file even if there's a running IGV instance available.
server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), true));
server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), false));
@ -392,6 +395,7 @@ public class HotSpotGraalManagementTest {
server.invoke(mbeanName, "dumpMethod", params, null);
boolean found = false;
String expectedIgvDumpSuffix = "[Arrays.asList(Object[])List].bgv";
Assert.assertTrue(tmpDir.toString() + " was not created or is not a directory", tmpDir.isDirectory());
List<String> dumpPathEntries = Arrays.asList(tmpDir.list());
for (String entry : dumpPathEntries) {
if (entry.endsWith(expectedIgvDumpSuffix)) {
@ -403,8 +407,11 @@ public class HotSpotGraalManagementTest {
dumpPathEntries.stream().collect(Collectors.joining(System.lineSeparator()))));
}
} finally {
deleteDirectory(tmpDir.toPath());
if (tmpDir.isDirectory()) {
deleteDirectory(tmpDir.toPath());
}
server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), originalDumpPath));
server.setAttribute(mbeanName, new Attribute(methodFilter.getName(), originalMethodFilter));
server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), originalPrintGraphFile));
server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), originalShowDumpFiles));
}

View File

@ -27,9 +27,13 @@ package org.graalvm.compiler.hotspot.test;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.hotspot.JVMCIVersionCheck;
import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version;
import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version2;
import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version3;
import org.junit.Assert;
import org.junit.Test;
@ -43,24 +47,37 @@ public class JVMCIVersionCheckTest extends GraalCompilerTest {
props.put(name, sprops.getProperty(name));
}
for (int i = 0; i < 100; i++) {
int minMajor = i;
int minMinor = 100 - i;
for (int j = 0; j < 100; j++) {
int major = j;
int minor = 100 - j;
long seed = Long.getLong("test.seed", System.nanoTime());
Random random = new Random(seed);
boolean ok = (major > minMajor) || (major == minMajor && minor >= minMinor);
for (String sep : new String[]{".", "-b"}) {
String javaVmVersion = String.format("prefix-jvmci-%03d%s%03d-suffix", major, sep, minor);
if (ok) {
JVMCIVersionCheck.check(props, minMajor, minMinor, "1.8", javaVmVersion, false);
} else {
try {
JVMCIVersionCheck.check(props, minMajor, minMinor, "1.8", javaVmVersion, false);
Assert.fail("expected to fail checking " + javaVmVersion + " against " + minMajor + "." + minMinor);
} catch (InternalError e) {
// pass
for (int i = 0; i < 50; i++) {
int minMajor = i;
int minMinor = 50 - i;
for (int j = 0; j < 50; j++) {
int major = j;
int minor = 50 - j;
for (int k = 0; k < 30; k++) {
int minBuild = random.nextInt(100);
int build = random.nextInt(100);
for (Version version : new Version[]{new Version2(major, minor), new Version3(major, minor, build)}) {
for (Version minVersion : new Version[]{new Version2(minMajor, minMinor), new Version3(minMajor, minMinor, minBuild)}) {
String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version);
if (!version.isLessThan(minVersion)) {
try {
JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false);
} catch (InternalError e) {
throw new AssertionError("Failed " + JVMCIVersionCheckTest.class.getSimpleName() + " with -Dtest.seed=" + seed, e);
}
} else {
try {
JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false);
Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion + " (-Dtest.seed=" + seed + ")");
} catch (InternalError e) {
// pass
}
}
}
}
}
@ -72,8 +89,9 @@ public class JVMCIVersionCheckTest extends GraalCompilerTest {
for (String version : new String[]{"0" + sep + Long.MAX_VALUE, Long.MAX_VALUE + sep + 0}) {
String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version);
try {
JVMCIVersionCheck.check(props, 0, 59, "1.8", javaVmVersion, false);
Assert.fail("expected to fail checking " + javaVmVersion + " against 0.59");
Version2 minVersion = new Version2(0, 59);
JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false);
Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion);
} catch (InternalError e) {
// pass
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot;
import org.graalvm.compiler.debug.GraalError;
import jdk.vm.ci.meta.JavaConstant;
/**
* A context for scoping the lifetime of foreign objects.
*
* The need for this mechanism is best explained with an example. When folding a GETFIELD bytecode
* denoting a {@code final static} non-primitive field, libgraal can create a {@link JavaConstant}
* wrapping a handle to the field's value in the HotSpot heap. This handle must be released before
* HotSpot can reclaim the object it references. Performing a compilation in the scope of a
* {@linkplain HotSpotGraalServices#openLocalCompilationContext local} context ensures the handle is
* released once the compilation completes, allowing the HotSpot GC to subsequently reclaim the
* HotSpot object. When libgraal creates data structures that outlive a single compilation and may
* contain foreign object references (e.g. snippet graphs), it must enter the
* {@linkplain HotSpotGraalServices#enterGlobalCompilationContext global} context. Foreign object
* handles created in the global context are only released once their {@link JavaConstant} wrappers
* are reclaimed by the libgraal GC.
*
* {@link CompilationContext}s have no impact on {@link JavaConstant}s that do not encapsulate a
* foreign object reference.
*
* The object returned by {@link HotSpotGraalServices#enterGlobalCompilationContext} or
* {@link HotSpotGraalServices#openLocalCompilationContext} should be used in a try-with-resources
* statement. Failure to close a context will almost certainly result in foreign objects being
* leaked.
*/
public class CompilationContext implements AutoCloseable {
private final AutoCloseable impl;
CompilationContext(AutoCloseable impl) {
this.impl = impl;
}
@Override
public void close() {
try {
impl.close();
} catch (Exception e) {
GraalError.shouldNotReachHere(e);
}
}
}

View File

@ -26,6 +26,7 @@ package org.graalvm.compiler.hotspot;
import static org.graalvm.compiler.hotspot.HotSpotGraalCompiler.fmt;
import static org.graalvm.compiler.hotspot.HotSpotGraalCompiler.str;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@ -35,9 +36,10 @@ import java.util.TreeSet;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.options.OptionKey;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -85,7 +87,7 @@ class CompilationCounters {
}
}
TTY.flush();
System.exit(-1);
HotSpotGraalServices.exit(-1);
}
}

View File

@ -96,9 +96,14 @@ public class CompilationTask {
return DebugContext.create(retryOptions, description, initialDebug.getGlobalMetrics(), logStream, factories);
}
@Override
protected void exitHostVM(int status) {
HotSpotGraalServices.exit(status);
}
@Override
public String toString() {
return getMethod().format("%H.%n(%p)");
return getMethod().format("%H.%n(%p) @ " + getEntryBCI());
}
@Override

View File

@ -238,7 +238,7 @@ class CompilationWatchDog implements Runnable, AutoCloseable {
TTY.printf("======================= WATCH DOG THREAD =======================%n" +
"%s took %d identical stack traces, which indicates a stuck compilation (id=%d) of %s%n%sExiting VM%n", this,
numberOfIdenticalStackTraces, currentId, fmt(currentMethod), fmt(lastStackTrace));
System.exit(-1);
HotSpotGraalServices.exit(-1);
}
} else if (newStackTrace) {
synchronized (CompilationWatchDog.class) {

View File

@ -200,7 +200,7 @@ public abstract class CompilerConfigurationFactory implements Comparable<Compile
for (CompilerConfigurationFactory candidate : getAllCandidates()) {
System.out.println(" " + candidate.name);
}
System.exit(0);
HotSpotGraalServices.exit(0);
} else if (value != null) {
for (CompilerConfigurationFactory candidate : GraalServices.load(CompilerConfigurationFactory.class)) {
if (candidate.name.equals(value)) {

View File

@ -111,39 +111,41 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable {
@SuppressWarnings("try")
CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault, OptionValues initialOptions) {
if (graalRuntime.isShutdown()) {
return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), true);
}
ResolvedJavaMethod method = request.getMethod();
if (graalRuntime.isBootstrapping()) {
if (DebugOptions.BootstrapInitializeOnly.getValue(initialOptions)) {
return HotSpotCompilationRequestResult.failure(String.format("Skip compilation because %s is enabled", DebugOptions.BootstrapInitializeOnly.getName()), true);
try (CompilationContext scope = HotSpotGraalServices.openLocalCompilationContext(request)) {
if (graalRuntime.isShutdown()) {
return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), true);
}
if (bootstrapWatchDog != null) {
if (bootstrapWatchDog.hitCriticalCompilationRateOrTimeout()) {
// Drain the compilation queue to expedite completion of the bootstrap
return HotSpotCompilationRequestResult.failure("hit critical bootstrap compilation rate or timeout", true);
ResolvedJavaMethod method = request.getMethod();
if (graalRuntime.isBootstrapping()) {
if (DebugOptions.BootstrapInitializeOnly.getValue(initialOptions)) {
return HotSpotCompilationRequestResult.failure(String.format("Skip compilation because %s is enabled", DebugOptions.BootstrapInitializeOnly.getName()), true);
}
if (bootstrapWatchDog != null) {
if (bootstrapWatchDog.hitCriticalCompilationRateOrTimeout()) {
// Drain the compilation queue to expedite completion of the bootstrap
return HotSpotCompilationRequestResult.failure("hit critical bootstrap compilation rate or timeout", true);
}
}
}
}
HotSpotCompilationRequest hsRequest = (HotSpotCompilationRequest) request;
CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, shouldRetainLocalVariables(hsRequest.getJvmciEnv()), installAsDefault);
OptionValues options = task.filterOptions(initialOptions);
try (CompilationWatchDog w1 = CompilationWatchDog.watch(method, hsRequest.getId(), options);
BootstrapWatchDog.Watch w2 = bootstrapWatchDog == null ? null : bootstrapWatchDog.watch(request);
CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(options);) {
if (compilationCounters != null) {
compilationCounters.countCompilation(method);
HotSpotCompilationRequest hsRequest = (HotSpotCompilationRequest) request;
CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, shouldRetainLocalVariables(hsRequest.getJvmciEnv()), installAsDefault);
OptionValues options = task.filterOptions(initialOptions);
try (CompilationWatchDog w1 = CompilationWatchDog.watch(method, hsRequest.getId(), options);
BootstrapWatchDog.Watch w2 = bootstrapWatchDog == null ? null : bootstrapWatchDog.watch(request);
CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(options);) {
if (compilationCounters != null) {
compilationCounters.countCompilation(method);
}
CompilationRequestResult r = null;
try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM);
Activation a = debug.activate()) {
r = task.runCompilation(debug);
}
assert r != null;
return r;
}
CompilationRequestResult r = null;
try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM);
Activation a = debug.activate()) {
r = task.runCompilation(debug);
}
assert r != null;
return r;
}
}

View File

@ -26,6 +26,9 @@ package org.graalvm.compiler.hotspot;
import jdk.vm.ci.hotspot.HotSpotMetaData;
/**
* JDK 13 version of {@code HotSpotGraalServices}.
*/
public class HotSpotGraalServices {
/**
@ -35,4 +38,17 @@ public class HotSpotGraalServices {
public static byte[] getImplicitExceptionBytes(HotSpotMetaData metaData) {
return metaData.implicitExceptionBytes();
}
public static CompilationContext enterGlobalCompilationContext() {
return null;
}
@SuppressWarnings("unused")
public static CompilationContext openLocalCompilationContext(Object description) {
return null;
}
public static void exit(int status) {
System.exit(status);
}
}

View File

@ -208,6 +208,7 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
return super.getSnippet(method, recursiveEntry, args, trackNodeSourcePosition, replaceePosition, options);
}
@SuppressWarnings("try")
private StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, Object[] args, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
boolean useEncodedGraphs = UseEncodedGraphs.getValue(options);
if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
@ -219,11 +220,15 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
if (getEncodedSnippets() == null) {
throw GraalError.shouldNotReachHere("encoded snippets not found");
}
StructuredGraph graph = getEncodedSnippets().getEncodedSnippet(method, this, args, allowAssumptions, options);
if (graph == null) {
throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)"));
// Snippets graphs can contain foreign object reference and
// outlive a single compilation.
try (CompilationContext scope = HotSpotGraalServices.enterGlobalCompilationContext()) {
StructuredGraph graph = getEncodedSnippets().getEncodedSnippet(method, this, args, allowAssumptions, options);
if (graph == null) {
throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)"));
}
return graph;
}
return graph;
}
} else {
assert registeredSnippets == null || registeredSnippets.contains(method) : "Asking for snippet method that was never registered: " + method.format("%H.%n(%p)");

View File

@ -42,6 +42,7 @@ import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.serviceprovider.GraalServices;
import org.graalvm.compiler.serviceprovider.ServiceProvider;
import jdk.vm.ci.common.NativeImageReinitialize;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.services.Services;
@ -96,7 +97,7 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
* initialization.
*/
class DelayedOutputStream extends OutputStream {
private volatile OutputStream lazy;
@NativeImageReinitialize private volatile OutputStream lazy;
private OutputStream lazy() {
if (lazy == null) {

View File

@ -43,4 +43,3 @@ abstract class IsGraalPredicateBase {
return HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.ByHolder;
}
}

View File

@ -28,6 +28,8 @@ import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Mechanism for checking that the current Java runtime environment supports the minimum JVMCI API
@ -41,8 +43,107 @@ import java.util.Properties;
*/
public final class JVMCIVersionCheck {
private static final int JVMCI8_MIN_MAJOR_VERSION = 19;
private static final int JVMCI8_MIN_MINOR_VERSION = 1;
private static final Version JVMCI8_MIN_VERSION = new Version3(19, 2, 1);
public interface Version {
boolean isLessThan(Version other);
static Version parse(String vmVersion) {
Matcher m = Pattern.compile(".*-jvmci-(\\d+)\\.(\\d+)-b(\\d+).*").matcher(vmVersion);
if (m.matches()) {
try {
int major = Integer.parseInt(m.group(1));
int minor = Integer.parseInt(m.group(2));
int build = Integer.parseInt(m.group(3));
return new Version3(major, minor, build);
} catch (NumberFormatException e) {
// ignore
}
}
m = Pattern.compile(".*-jvmci-(\\d+)(?:\\.|-b)(\\d+).*").matcher(vmVersion);
if (m.matches()) {
try {
int major = Integer.parseInt(m.group(1));
int minor = Integer.parseInt(m.group(2));
return new Version2(major, minor);
} catch (NumberFormatException e) {
// ignore
}
}
return null;
}
}
public static class Version2 implements Version {
private final int major;
private final int minor;
public Version2(int major, int minor) {
this.major = major;
this.minor = minor;
}
@Override
public boolean isLessThan(Version other) {
if (other.getClass() == Version3.class) {
return true;
}
Version2 o = (Version2) other;
if (this.major < o.major) {
return true;
}
if (this.major == o.major && this.minor < o.minor) {
return true;
}
return false;
}
@Override
public String toString() {
if (major >= 19) {
return String.format("%d-b%02d", major, minor);
} else {
return String.format("%d.%d", major, minor);
}
}
}
public static class Version3 implements Version {
private final int major;
private final int minor;
private final int build;
public Version3(int major, int minor, int build) {
this.major = major;
this.minor = minor;
this.build = build;
}
@Override
public boolean isLessThan(Version other) {
if (other.getClass() == Version2.class) {
return false;
}
Version3 o = (Version3) other;
if (this.major < o.major) {
return true;
}
if (this.major == o.major) {
if (this.minor < o.minor) {
return true;
}
if (this.minor == o.minor && this.build < o.build) {
return true;
}
}
return false;
}
@Override
public String toString() {
return String.format("%d.%d-b%02d", major, minor, build);
}
}
private static void failVersionCheck(Map<String, String> props, boolean exit, String reason, Object... args) {
Formatter errorMessage = new Formatter().format(reason, args);
@ -53,9 +154,7 @@ public final class JVMCIVersionCheck {
errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
errorMessage.format("Currently used VM configuration is: %s%n", vmName);
if (props.get("java.specification.version").compareTo("1.9") < 0) {
errorMessage.format("Download the latest JVMCI JDK 8 from " +
"https://www.oracle.com/technetwork/graalvm/downloads/index.html or " +
"https://github.com/graalvm/openjdk8-jvmci-builder/releases");
errorMessage.format("Download the latest JVMCI JDK 8 from https://github.com/graalvm/openjdk8-jvmci-builder/releases");
} else {
errorMessage.format("Download JDK 11 or later.");
}
@ -74,7 +173,6 @@ public final class JVMCIVersionCheck {
private final String javaSpecVersion;
private final String vmVersion;
private int cursor;
private final Map<String, String> props;
private JVMCIVersionCheck(Map<String, String> props, String javaSpecVersion, String vmVersion) {
@ -85,112 +183,28 @@ public final class JVMCIVersionCheck {
static void check(Map<String, String> props, boolean exitOnFailure) {
JVMCIVersionCheck checker = new JVMCIVersionCheck(props, props.get("java.specification.version"), props.get("java.vm.version"));
checker.run(exitOnFailure, JVMCI8_MIN_MAJOR_VERSION, JVMCI8_MIN_MINOR_VERSION);
checker.run(exitOnFailure, JVMCI8_MIN_VERSION);
}
/**
* Entry point for testing.
*/
public static void check(Map<String, String> props,
int jvmci8MinMajorVersion,
int jvmci8MinMinorVersion,
Version minVersion,
String javaSpecVersion,
String javaVmVersion,
boolean exitOnFailure) {
String javaVmVersion, boolean exitOnFailure) {
JVMCIVersionCheck checker = new JVMCIVersionCheck(props, javaSpecVersion, javaVmVersion);
checker.run(exitOnFailure, jvmci8MinMajorVersion, jvmci8MinMinorVersion);
checker.run(exitOnFailure, minVersion);
}
/**
* Parses a positive decimal number at {@link #cursor}.
*
* @return -1 if there is no positive decimal number at {@link #cursor}
*/
private int parseNumber() {
int result = -1;
while (cursor < vmVersion.length()) {
int digit = vmVersion.charAt(cursor) - '0';
if (digit >= 0 && digit <= 9) {
if (result == -1) {
result = digit;
} else {
long r = (long) result * (long) 10;
if ((int) r != r) {
// Overflow
return -1;
}
result = (int) r + digit;
}
cursor++;
} else {
break;
}
}
return result;
}
/**
* Parse {@code "."} or {@code "-b"} at {@link #cursor}.
*
* @return {@code true} iff there was an expected separator at {@link #cursor}
*/
private boolean parseSeparator() {
if (cursor < vmVersion.length()) {
char ch = vmVersion.charAt(cursor);
if (ch == '.') {
cursor++;
return true;
}
if (ch == '-') {
cursor++;
if (cursor < vmVersion.length()) {
if (vmVersion.charAt(cursor) == 'b') {
cursor++;
return true;
}
}
return false;
}
}
return false;
}
private static String getJVMCIVersionString(int major, int minor) {
if (major >= 19) {
return String.format("%d-b%02d", major, minor);
} else {
return String.format("%d.%d", major, minor);
}
}
private void run(boolean exitOnFailure, int jvmci8MinMajorVersion, int jvmci8MinMinorVersion) {
// Don't use regular expressions to minimize Graal startup time
private void run(boolean exitOnFailure, Version minVersion) {
if (javaSpecVersion.compareTo("1.9") < 0) {
cursor = vmVersion.indexOf("-jvmci-");
if (cursor >= 0) {
cursor += "-jvmci-".length();
int major = parseNumber();
if (major == -1) {
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion);
return;
}
if (parseSeparator()) {
int minor = parseNumber();
if (minor == -1) {
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI minor version from java.vm.version property: %s.%n", vmVersion);
return;
}
if (major > jvmci8MinMajorVersion || (major >= jvmci8MinMajorVersion && minor >= jvmci8MinMinorVersion)) {
return;
}
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n",
getJVMCIVersionString(major, minor), getJVMCIVersionString(jvmci8MinMajorVersion, jvmci8MinMinorVersion));
return;
Version v = Version.parse(vmVersion);
if (v != null) {
if (v.isLessThan(minVersion)) {
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion);
}
return;
}
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);

View File

@ -182,7 +182,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
/**
* HotSpot implementation of {@link LoweringProvider}.
*/
public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider implements HotSpotLoweringProvider {
public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider implements HotSpotLoweringProvider {
protected final HotSpotGraalRuntimeProvider runtime;
protected final HotSpotRegistersProvider registers;

View File

@ -44,6 +44,7 @@ import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.TypeReference;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
@ -106,6 +107,7 @@ import org.graalvm.compiler.word.WordTypes;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.hotspot.VMIntrinsicMethod;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.JavaKind;
@ -429,8 +431,6 @@ public class HotSpotGraphBuilderPlugins {
r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
}
public static final String cbcEncryptName;
public static final String cbcDecryptName;
public static final String aesEncryptName;
public static final String aesDecryptName;
@ -439,15 +439,11 @@ public class HotSpotGraphBuilderPlugins {
static {
if (JavaVersionUtil.JAVA_SPEC <= 8) {
cbcEncryptName = "encrypt";
cbcDecryptName = "decrypt";
aesEncryptName = "encryptBlock";
aesDecryptName = "decryptBlock";
reflectionClass = "sun.reflect.Reflection";
constantPoolClass = "sun.reflect.ConstantPool";
} else {
cbcEncryptName = "implEncrypt";
cbcDecryptName = "implDecrypt";
aesEncryptName = "implEncryptBlock";
aesDecryptName = "implDecryptBlock";
reflectionClass = "jdk.internal.reflect.Reflection";
@ -455,6 +451,19 @@ public class HotSpotGraphBuilderPlugins {
}
}
public static boolean cbcUsesImplNames(GraalHotSpotVMConfig config) {
for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
if ("com/sun/crypto/provider/CipherBlockChaining".equals(intrinsic.declaringClass)) {
if ("encrypt".equals(intrinsic.name)) {
return false;
} else if ("implEncrypt".equals(intrinsic.name)) {
return true;
}
}
}
throw GraalError.shouldNotReachHere();
}
private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
if (config.useAESIntrinsics) {
assert config.aescryptEncryptBlockStub != 0L;
@ -464,9 +473,15 @@ public class HotSpotGraphBuilderPlugins {
String arch = config.osArch;
String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : "";
Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", bytecodeProvider);
boolean implNames = cbcUsesImplNames(config);
String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class,
int.class);
r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", bytecodeProvider);
r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);

View File

@ -244,4 +244,3 @@ public final class HotSpotNodePlugin implements NodePlugin, TypePlugin {
private static final LocationIdentity JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION = NamedLocationIdentity.mutable("JavaThread::_should_post_on_exceptions_flag");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it

View File

@ -41,7 +41,6 @@ import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.loop.phases.LoopTransformations;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.EntryMarkerNode;
import org.graalvm.compiler.nodes.EntryProxyNode;
import org.graalvm.compiler.nodes.FixedGuardNode;
@ -159,11 +158,8 @@ public class OnStackReplacementPhase extends Phase {
LoopEx loop = loops.loop(l);
loop.loopBegin().markOsrLoop();
LoopTransformations.peel(loop);
osr.replaceAtUsages(InputType.Guard, AbstractBeginNode.prevBegin((FixedNode) osr.predecessor()));
for (Node usage : osr.usages().snapshot()) {
EntryProxyNode proxy = (EntryProxyNode) usage;
proxy.replaceAndDelete(proxy.value());
}
osr.prepareDelete();
GraphUtil.removeFixedWithUnusedInputs(osr);
debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement loop peeling result");
} while (true);
@ -228,6 +224,7 @@ public class OnStackReplacementPhase extends Phase {
}
osr.replaceAtUsages(InputType.Guard, osrStart);
osr.replaceAtUsages(InputType.Anchor, osrStart);
}
debug.dump(DebugContext.DETAILED_LEVEL, graph, "OnStackReplacement after replacing entry proxies");
GraphUtil.killCFG(start);

View File

@ -212,14 +212,27 @@ public class NewObjectSnippets implements Snippets {
}
@Snippet
public static Object allocateInstance(@ConstantParameter long size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents,
@ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext,
public static Object allocateInstance(@ConstantParameter long size,
KlassPointer hub,
Word prototypeMarkWord,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter boolean constantSize,
@ConstantParameter String typeContext,
@ConstantParameter Counters counters) {
return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters));
return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, constantSize, typeContext, counters));
}
public static Object allocateInstanceHelper(long size, KlassPointer hub, Word prototypeMarkWord, boolean fillContents,
Register threadRegister, boolean constantSize, String typeContext, Counters counters) {
public static Object allocateInstanceHelper(long size,
KlassPointer hub,
Word prototypeMarkWord,
boolean fillContents,
boolean emitMemoryBarrier,
Register threadRegister,
boolean constantSize,
String typeContext,
Counters counters) {
Object result;
Word thread = registerAsWord(threadRegister);
Word top = readTlabTop(thread);
@ -228,7 +241,7 @@ public class NewObjectSnippets implements Snippets {
if (useTLAB(INJECTED_VMCONFIG) && probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) {
writeTlabTop(thread, newTop);
emitPrefetchAllocate(newTop, false);
result = formatObject(hub, size, top, prototypeMarkWord, fillContents, constantSize, counters);
result = formatObject(hub, size, top, prototypeMarkWord, fillContents, emitMemoryBarrier, constantSize, counters);
} else {
Counters theCounters = counters;
if (theCounters != null && theCounters.stub != null) {
@ -255,18 +268,27 @@ public class NewObjectSnippets implements Snippets {
private static native Object newInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub);
@Snippet
public static Object allocateInstancePIC(@ConstantParameter long size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents,
@ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext,
public static Object allocateInstancePIC(@ConstantParameter long size,
KlassPointer hub,
Word prototypeMarkWord,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter boolean constantSize,
@ConstantParameter String typeContext,
@ConstantParameter Counters counters) {
// Klass must be initialized by the time the first instance is allocated, therefore we can
// just load it from the corresponding cell and avoid the resolution check. We have to use a
// fixed load though, to prevent it from floating above the initialization.
KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters));
return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, constantSize, typeContext, counters));
}
@Snippet
public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter Counters counters) {
if (probability(SLOW_PATH_PROBABILITY, type == null)) {
DeoptimizeNode.deopt(None, RuntimeConstraint);
@ -277,10 +299,15 @@ public class NewObjectSnippets implements Snippets {
DeoptimizeNode.deopt(None, RuntimeConstraint);
}
return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, counters, nonNullType));
return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, emitMemoryBarrier, threadRegister, counters, nonNullType));
}
private static Object allocateInstanceDynamicHelper(Class<?> type, boolean fillContents, Register threadRegister, Counters counters, Class<?> nonNullType) {
private static Object allocateInstanceDynamicHelper(Class<?> type,
boolean fillContents,
boolean emitMemoryBarrier,
Register threadRegister,
Counters counters,
Class<?> nonNullType) {
KlassPointer hub = ClassGetHubNode.readClass(nonNullType);
if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) {
KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor());
@ -299,7 +326,7 @@ public class NewObjectSnippets implements Snippets {
* FIXME(je,ds): we should actually pass typeContext instead of "" but late
* binding of parameters is not yet supported by the GraphBuilderPlugin system.
*/
return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", counters);
return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, false, "", counters);
}
} else {
DeoptimizeNode.deopt(None, RuntimeConstraint);
@ -320,6 +347,7 @@ public class NewObjectSnippets implements Snippets {
@ConstantParameter int headerSize,
@ConstantParameter int log2ElementSize,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
@ -328,7 +356,7 @@ public class NewObjectSnippets implements Snippets {
// Primitive array types are eagerly pre-resolved. We can use a floating load.
KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters);
emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters);
}
@Snippet
@ -338,6 +366,7 @@ public class NewObjectSnippets implements Snippets {
@ConstantParameter int headerSize,
@ConstantParameter int log2ElementSize,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
@ -346,7 +375,7 @@ public class NewObjectSnippets implements Snippets {
// Array type would be resolved by dominating resolution.
KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters);
emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters);
}
@Snippet
@ -356,6 +385,7 @@ public class NewObjectSnippets implements Snippets {
@ConstantParameter int headerSize,
@ConstantParameter int log2ElementSize,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
@ -367,7 +397,7 @@ public class NewObjectSnippets implements Snippets {
headerSize,
log2ElementSize,
fillContents,
threadRegister,
emitMemoryBarrier, threadRegister,
maybeUnroll,
typeContext,
useBulkZeroing,
@ -384,8 +414,18 @@ public class NewObjectSnippets implements Snippets {
return config.areNullAllocationStubsAvailable();
}
private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, Register threadRegister,
boolean maybeUnroll, String typeContext, boolean useBulkZeroing, Counters counters) {
private static Object allocateArrayImpl(KlassPointer hub,
int length,
Word prototypeMarkWord,
int headerSize,
int log2ElementSize,
boolean fillContents,
boolean emitMemoryBarrier,
Register threadRegister,
boolean maybeUnroll,
String typeContext,
boolean useBulkZeroing,
Counters counters) {
Object result;
long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize);
Word thread = registerAsWord(threadRegister);
@ -400,7 +440,7 @@ public class NewObjectSnippets implements Snippets {
if (theCounters != null && theCounters.arrayLoopInit != null) {
theCounters.arrayLoopInit.inc();
}
result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, useBulkZeroing, counters);
result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, useBulkZeroing, counters);
} else {
result = newArrayStub(hub, length);
}
@ -461,19 +501,29 @@ public class NewObjectSnippets implements Snippets {
Class<?> voidClass,
int length,
@ConstantParameter boolean fillContents,
@ConstantParameter boolean emitMemoryBarrier,
@ConstantParameter Register threadRegister,
@ConstantParameter JavaKind knownElementKind,
@ConstantParameter int knownLayoutHelper,
@ConstantParameter boolean useBulkZeroing,
Word prototypeMarkWord,
@ConstantParameter Counters counters) {
Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind,
Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, emitMemoryBarrier, threadRegister, knownElementKind,
knownLayoutHelper, useBulkZeroing, prototypeMarkWord, counters);
return result;
}
private static Object allocateArrayDynamicImpl(Class<?> elementType, Class<?> voidClass, int length, boolean fillContents, Register threadRegister, JavaKind knownElementKind,
int knownLayoutHelper, boolean useBulkZeroing, Word prototypeMarkWord, Counters counters) {
private static Object allocateArrayDynamicImpl(Class<?> elementType,
Class<?> voidClass,
int length,
boolean fillContents,
boolean emitMemoryBarrier,
Register threadRegister,
JavaKind knownElementKind,
int knownLayoutHelper,
boolean useBulkZeroing,
Word prototypeMarkWord,
Counters counters) {
/*
* We only need the dynamic check for void when we have no static information from
* knownElementKind.
@ -516,7 +566,7 @@ public class NewObjectSnippets implements Snippets {
int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
threadRegister, false, "dynamic type", useBulkZeroing, counters);
emitMemoryBarrier, threadRegister, false, "dynamic type", useBulkZeroing, counters);
return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
}
@ -650,7 +700,14 @@ public class NewObjectSnippets implements Snippets {
/**
* Formats some allocated memory with an object header and zeroes out the rest.
*/
private static Object formatObject(KlassPointer hub, long size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, Counters counters) {
private static Object formatObject(KlassPointer hub,
long size,
Word memory,
Word compileTimePrototypeMarkWord,
boolean fillContents,
boolean emitMemoryBarrier,
boolean constantSize,
Counters counters) {
Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
initializeObjectHeader(memory, prototypeMarkWord, hub);
if (fillContents) {
@ -658,7 +715,9 @@ public class NewObjectSnippets implements Snippets {
} else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
fillWithGarbage(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, counters);
}
MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init());
if (emitMemoryBarrier) {
MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init());
}
return memory.toObjectNonNull();
}
@ -677,8 +736,17 @@ public class NewObjectSnippets implements Snippets {
/**
* Formats some allocated memory with an object header and zeroes out the rest.
*/
private static Object formatArray(KlassPointer hub, long allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll,
boolean useBulkZeroing, Counters counters) {
private static Object formatArray(KlassPointer hub,
long allocationSize,
int length,
int headerSize,
Word memory,
Word prototypeMarkWord,
boolean fillContents,
boolean emitMemoryBarrier,
boolean maybeUnroll,
boolean useBulkZeroing,
Counters counters) {
memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init());
/*
* store hub last as the concurrent garbage collectors assume length is valid if hub field
@ -690,7 +758,9 @@ public class NewObjectSnippets implements Snippets {
} else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
fillWithGarbage(allocationSize, memory, false, headerSize, maybeUnroll, counters);
}
MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init());
if (emitMemoryBarrier) {
MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init());
}
return memory.toObjectNonNull();
}
@ -756,6 +826,7 @@ public class NewObjectSnippets implements Snippets {
args.add("hub", hub);
args.add("prototypeMarkWord", type.prototypeMarkWord());
args.addConst("fillContents", newInstanceNode.fillContents());
args.addConst("emitMemoryBarrier", newInstanceNode.emitMemoryBarrier());
args.addConst("threadRegister", registers.getThreadRegister());
args.addConst("constantSize", true);
args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? type.toJavaName(false) : "");
@ -799,6 +870,7 @@ public class NewObjectSnippets implements Snippets {
args.addConst("headerSize", headerSize);
args.addConst("log2ElementSize", log2ElementSize);
args.addConst("fillContents", newArrayNode.fillContents());
args.addConst("emitMemoryBarrier", newArrayNode.emitMemoryBarrier());
args.addConst("threadRegister", registers.getThreadRegister());
args.addConst("maybeUnroll", length.isConstant());
args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : "");
@ -816,6 +888,7 @@ public class NewObjectSnippets implements Snippets {
assert classClass != null;
args.add("classClass", classClass);
args.addConst("fillContents", newInstanceNode.fillContents());
args.addConst("emitMemoryBarrier", newInstanceNode.emitMemoryBarrier());
args.addConst("threadRegister", registers.getThreadRegister());
args.addConst("counters", counters);
@ -833,6 +906,7 @@ public class NewObjectSnippets implements Snippets {
ValueNode length = newArrayNode.length();
args.add("length", length.isAlive() ? length : graph.addOrUniqueWithInputs(length));
args.addConst("fillContents", newArrayNode.fillContents());
args.addConst("emitMemoryBarrier", newArrayNode.emitMemoryBarrier());
args.addConst("threadRegister", registers.getThreadRegister());
/*
* We use Kind.Illegal as a marker value instead of null because constant snippet

View File

@ -391,7 +391,6 @@ import org.graalvm.compiler.nodes.extended.LoadArrayComponentHubNode;
import org.graalvm.compiler.nodes.extended.LoadHubNode;
import org.graalvm.compiler.nodes.extended.MembarNode;
import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode;
@ -624,7 +623,6 @@ public class BytecodeParser implements GraphBuilderContext {
}
static class IntrinsicScope extends InliningScope {
StateSplit returnStateSplit;
ArrayList<StateSplit> invalidStateUsers;
IntrinsicScope(BytecodeParser parser) {
@ -635,6 +633,7 @@ public class BytecodeParser implements GraphBuilderContext {
super(parser, callee, args);
}
@SuppressWarnings("unlikely-arg-type")
@Override
public void close() {
IntrinsicContext intrinsic = parser.intrinsicContext;
@ -1405,7 +1404,7 @@ public class BytecodeParser implements GraphBuilderContext {
if (profile == null || profile.getNotRecordedProbability() > 0.0) {
return null;
} else {
return append(new ValueAnchorNode(null));
return BeginNode.prevBegin(lastInstr);
}
}
@ -4794,6 +4793,9 @@ public class BytecodeParser implements GraphBuilderContext {
}
}
private static final int SWITCH_DEOPT_UNSEEN = -2;
private static final int SWITCH_DEOPT_SEEN = -1;
private void genSwitch(BytecodeSwitch bs) {
int bci = bci();
ValueNode value = frameState.pop(JavaKind.Int);
@ -4811,20 +4813,16 @@ public class BytecodeParser implements GraphBuilderContext {
ArrayList<BciBlock> actualSuccessors = new ArrayList<>();
int[] keys = new int[nofCases];
int[] keySuccessors = new int[nofCasesPlusDefault];
int deoptSuccessorIndex = -1;
int deoptSuccessorIndex = SWITCH_DEOPT_UNSEEN;
int nextSuccessorIndex = 0;
boolean constantValue = value.isConstant();
for (int i = 0; i < nofCasesPlusDefault; i++) {
if (i < nofCases) {
keys[i] = bs.keyAt(i);
}
if (!constantValue && isNeverExecutedCode(keyProbabilities[i])) {
if (deoptSuccessorIndex < 0) {
deoptSuccessorIndex = nextSuccessorIndex++;
actualSuccessors.add(null);
}
keySuccessors[i] = deoptSuccessorIndex;
deoptSuccessorIndex = SWITCH_DEOPT_SEEN;
keySuccessors[i] = SWITCH_DEOPT_SEEN;
} else {
int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
@ -4859,20 +4857,31 @@ public class BytecodeParser implements GraphBuilderContext {
*
* The following code rewires deoptimization stub to existing resolved branch target if
* the target is connected by more than 1 cases.
*
* If this operation rewires every deoptimization seen to an existing branch, care is
* taken that we do not spawn a branch that will never be taken.
*/
if (deoptSuccessorIndex >= 0) {
int[] connectedCases = new int[nextSuccessorIndex];
if (deoptSuccessorIndex == SWITCH_DEOPT_SEEN) {
int[] connectedCases = new int[nextSuccessorIndex + 1];
for (int i = 0; i < nofCasesPlusDefault; i++) {
connectedCases[keySuccessors[i]]++;
connectedCases[keySuccessors[i] + 1]++;
}
for (int i = 0; i < nofCasesPlusDefault; i++) {
if (keySuccessors[i] == deoptSuccessorIndex) {
if (keySuccessors[i] == SWITCH_DEOPT_SEEN) {
int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
int rewiredIndex = info.actualIndex;
if (rewiredIndex >= 0 && connectedCases[rewiredIndex] > 1) {
if (rewiredIndex >= 0 && connectedCases[rewiredIndex + 1] > 1) {
// Rewire
keySuccessors[i] = info.actualIndex;
} else {
if (deoptSuccessorIndex == SWITCH_DEOPT_SEEN) {
// Spawn deopt successor if needed.
deoptSuccessorIndex = nextSuccessorIndex++;
actualSuccessors.add(null);
}
keySuccessors[i] = deoptSuccessorIndex;
}
}
}

View File

@ -528,8 +528,8 @@ public class AArch64Move {
break;
case Object:
if (input.isNull()) {
if (crb.mustReplaceWithNullRegister(input)) {
masm.mov(64, dst, crb.nullRegister);
if (crb.mustReplaceWithUncompressedNullRegister(input)) {
masm.mov(64, dst, crb.uncompressedNullRegister);
} else {
masm.mov(dst, 0);
}
@ -725,7 +725,7 @@ public class AArch64Move {
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
Register nullRegister = crb.nullRegister;
Register nullRegister = crb.uncompressedNullRegister;
if (!nullRegister.equals(Register.None)) {
emitConversion(asRegister(result), asRegister(input), nullRegister, masm);
}

View File

@ -645,4 +645,3 @@ public final class AMD64ArrayIndexOfOp extends AMD64LIRInstruction {
return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature);
}
}

View File

@ -213,7 +213,7 @@ public class AMD64ControlFlow {
masm.cmpq(keyRegister, (AMD64Address) crb.asLongConstRef(jc));
break;
case Object:
AMD64Move.const2reg(crb, masm, asRegister(scratch), jc);
AMD64Move.const2reg(crb, masm, asRegister(scratch), jc, AMD64Kind.QWORD);
masm.cmpptr(keyRegister, asRegister(scratch));
break;
default:

View File

@ -156,7 +156,7 @@ public class AMD64Move {
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
if (isRegister(result)) {
const2reg(crb, masm, asRegister(result), input);
const2reg(crb, masm, asRegister(result), input, (AMD64Kind) result.getPlatformKind());
} else {
assert isStackSlot(result);
const2stack(crb, masm, result, input);
@ -557,7 +557,7 @@ public class AMD64Move {
}
} else if (isJavaConstant(input)) {
if (isRegister(result)) {
const2reg(crb, masm, asRegister(result), asJavaConstant(input));
const2reg(crb, masm, asRegister(result), asJavaConstant(input), moveKind);
} else if (isStackSlot(result)) {
const2stack(crb, masm, result, asJavaConstant(input));
} else {
@ -645,7 +645,7 @@ public class AMD64Move {
}
}
public static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, JavaConstant input) {
public static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, JavaConstant input, AMD64Kind moveKind) {
/*
* Note: we use the kind of the input operand (and not the kind of the result operand)
* because they don't match in all cases. For example, an object constant can be loaded to a
@ -691,20 +691,34 @@ public class AMD64Move {
}
break;
case Object:
assert moveKind != null : "a nun-null moveKind is required for loading an object constant";
// Do not optimize with an XOR as this instruction may be between
// a CMP and a Jcc in which case the XOR will modify the condition
// flags and interfere with the Jcc.
if (input.isNull()) {
if (crb.mustReplaceWithNullRegister(input)) {
masm.movq(result, crb.nullRegister);
if (moveKind == AMD64Kind.QWORD && crb.mustReplaceWithUncompressedNullRegister(input)) {
masm.movq(result, crb.uncompressedNullRegister);
} else {
// Upper bits will be zeroed so this also works for narrow oops
masm.movslq(result, 0);
}
} else if (crb.target.inlineObjects) {
crb.recordInlineDataInCode(input);
masm.movq(result, 0xDEADDEADDEADDEADL, true);
} else {
masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0));
if (crb.target.inlineObjects) {
crb.recordInlineDataInCode(input);
if (moveKind == AMD64Kind.DWORD) {
// Support for narrow oops
masm.movl(result, 0xDEADDEAD, true);
} else {
masm.movq(result, 0xDEADDEADDEADDEADL, true);
}
} else {
if (moveKind == AMD64Kind.DWORD) {
// Support for narrow oops
masm.movl(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0));
} else {
masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0));
}
}
}
break;
default:
@ -752,13 +766,13 @@ public class AMD64Move {
break;
case Object:
if (input.isNull()) {
if (crb.mustReplaceWithNullRegister(input)) {
masm.movq(dest, crb.nullRegister);
if (crb.mustReplaceWithUncompressedNullRegister(input)) {
masm.movq(dest, crb.uncompressedNullRegister);
return;
}
imm = 0;
} else {
throw GraalError.shouldNotReachHere("Non-null object constants must be in register");
throw GraalError.shouldNotReachHere("Non-null object constants must be in a register");
}
break;
default:
@ -941,7 +955,7 @@ public class AMD64Move {
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
Register nullRegister = crb.nullRegister;
Register nullRegister = crb.uncompressedNullRegister;
if (!nullRegister.equals(Register.None)) {
emitConversion(asRegister(result), asRegister(input), nullRegister, masm);
}

View File

@ -34,6 +34,7 @@ import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.framemap.FrameMap;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterSaveLayout;
import jdk.vm.ci.meta.JavaConstant;
@ -66,7 +67,7 @@ public final class AMD64ZapRegistersOp extends AMD64LIRInstruction implements Sa
for (int i = 0; i < zappedRegisters.length; i++) {
Register reg = zappedRegisters[i];
if (reg != null) {
AMD64Move.const2reg(crb, masm, reg, zapValues[i]);
AMD64Move.const2reg(crb, masm, reg, zapValues[i], AMD64Kind.QWORD);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -35,6 +35,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRRIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.asm.amd64.AVXKind;
import org.graalvm.compiler.lir.ConstantValue;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@ -42,6 +43,7 @@ import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.meta.AllocatableValue;
public class AMD64VectorBinary {
@ -102,6 +104,38 @@ public class AMD64VectorBinary {
}
}
public static final class AVXBinaryConstFloatOp extends AMD64LIRInstruction {
public static final LIRInstructionClass<AVXBinaryConstFloatOp> TYPE = LIRInstructionClass.create(AVXBinaryConstFloatOp.class);
@Opcode private final VexRVMOp opcode;
private final AVXKind.AVXSize size;
@Def({REG}) protected AllocatableValue result;
@Use({REG}) protected AllocatableValue x;
protected ConstantValue y;
public AVXBinaryConstFloatOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, ConstantValue y) {
super(TYPE);
assert y.getPlatformKind() == AMD64Kind.SINGLE || y.getPlatformKind() == AMD64Kind.DOUBLE;
this.opcode = opcode;
this.size = size;
this.result = result;
this.x = x;
this.y = y;
}
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
if (y.getPlatformKind() == AMD64Kind.SINGLE) {
opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asFloatConstRef(y.getJavaConstant()));
} else {
assert y.getPlatformKind() == AMD64Kind.DOUBLE;
opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asDoubleConstRef(y.getJavaConstant()));
}
}
}
public static final class AVXBinaryMemoryOp extends AMD64LIRInstruction {
public static final LIRInstructionClass<AVXBinaryMemoryOp> TYPE = LIRInstructionClass.create(AVXBinaryMemoryOp.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -99,7 +99,7 @@ public class ConstantStackCastTest extends LIRTest {
}
@Test
public void runByte() throws Throwable {
public void runByte() {
runTest("testByte", (byte) 0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -254,7 +254,7 @@ public abstract class LIRTest extends JTTTest {
@java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(ElementType.METHOD)
public static @interface LIRIntrinsic {
public @interface LIRIntrinsic {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -54,7 +54,7 @@ public class LIRTestTest extends LIRTest {
}
@Test
public void runInt() throws Throwable {
public void runInt() {
runTest("testGetOutput", Integer.MIN_VALUE, 0, supply(() -> new int[3]));
runTest("testGetOutput", -1, Integer.MAX_VALUE, supply(() -> new int[3]));
runTest("testGetOutput", 0, 42, supply(() -> new int[3]));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -98,7 +98,7 @@ public class StackMoveTest extends LIRTest {
}
@Test
public void runInt() throws Throwable {
public void runInt() {
runTest("testInt", Integer.MIN_VALUE, supply(() -> new int[4]));
runTest("testInt", -1, supply(() -> new int[4]));
runTest("testInt", 0, supply(() -> new int[4]));
@ -125,7 +125,7 @@ public class StackMoveTest extends LIRTest {
}
@Test
public void runLong() throws Throwable {
public void runLong() {
runTest("testLong", Long.MIN_VALUE, supply(() -> new long[3]));
runTest("testLong", -1L, supply(() -> new long[3]));
runTest("testLong", 0L, supply(() -> new long[3]));
@ -152,7 +152,7 @@ public class StackMoveTest extends LIRTest {
}
@Test
public void runFloat() throws Throwable {
public void runFloat() {
runTest("testFloat", Float.MIN_VALUE, supply(() -> new float[3]));
runTest("testFloat", -1f, supply(() -> new float[3]));
runTest("testFloat", -0.1f, supply(() -> new float[3]));
@ -217,7 +217,7 @@ public class StackMoveTest extends LIRTest {
}
@Test
public void runShort() throws Throwable {
public void runShort() {
runTest("testShort", Short.MIN_VALUE, supply(() -> new short[3]));
runTest("testShort", (short) -1, supply(() -> new short[3]));
runTest("testShort", (short) 0, supply(() -> new short[3]));
@ -251,7 +251,7 @@ public class StackMoveTest extends LIRTest {
}
@Test
public void runByte() throws Throwable {
public void runByte() {
runTest("testByte", Byte.MIN_VALUE, supply(() -> new byte[3]));
runTest("testByte", (byte) -1, supply(() -> new byte[3]));
runTest("testByte", (byte) 0, supply(() -> new byte[3]));

Some files were not shown because too many files have changed in this diff Show More