Merge
This commit is contained in:
commit
150ca9b5b1
@ -114,3 +114,4 @@ b4acf10eb134fe930802c97e36db65e7ccb544b5 jdk7-b104
|
|||||||
1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106
|
1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106
|
||||||
cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05
|
cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05
|
||||||
688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06
|
688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06
|
||||||
|
0000000000000000000000000000000000000000 hs19-b06
|
||||||
|
@ -1037,7 +1037,7 @@ public class CommandProcessor {
|
|||||||
public void prologue(Address start, Address end) {
|
public void prologue(Address start, Address end) {
|
||||||
}
|
}
|
||||||
public void visit(CodeBlob blob) {
|
public void visit(CodeBlob blob) {
|
||||||
fout.println(gen.genHTML(blob.instructionsBegin()));
|
fout.println(gen.genHTML(blob.contentBegin()));
|
||||||
}
|
}
|
||||||
public void epilogue() {
|
public void epilogue() {
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -54,7 +54,7 @@ public class Runtime1 {
|
|||||||
|
|
||||||
/** FIXME: consider making argument "type-safe" in Java port */
|
/** FIXME: consider making argument "type-safe" in Java port */
|
||||||
public Address entryFor(int id) {
|
public Address entryFor(int id) {
|
||||||
return blobFor(id).instructionsBegin();
|
return blobFor(id).codeBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FIXME: consider making argument "type-safe" in Java port */
|
/** FIXME: consider making argument "type-safe" in Java port */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,7 +39,8 @@ public class CodeBlob extends VMObject {
|
|||||||
private static CIntegerField sizeField;
|
private static CIntegerField sizeField;
|
||||||
private static CIntegerField headerSizeField;
|
private static CIntegerField headerSizeField;
|
||||||
private static CIntegerField relocationSizeField;
|
private static CIntegerField relocationSizeField;
|
||||||
private static CIntegerField instructionsOffsetField;
|
private static CIntegerField contentOffsetField;
|
||||||
|
private static CIntegerField codeOffsetField;
|
||||||
private static CIntegerField frameCompleteOffsetField;
|
private static CIntegerField frameCompleteOffsetField;
|
||||||
private static CIntegerField dataOffsetField;
|
private static CIntegerField dataOffsetField;
|
||||||
private static CIntegerField frameSizeField;
|
private static CIntegerField frameSizeField;
|
||||||
@ -68,7 +69,8 @@ public class CodeBlob extends VMObject {
|
|||||||
headerSizeField = type.getCIntegerField("_header_size");
|
headerSizeField = type.getCIntegerField("_header_size");
|
||||||
relocationSizeField = type.getCIntegerField("_relocation_size");
|
relocationSizeField = type.getCIntegerField("_relocation_size");
|
||||||
frameCompleteOffsetField = type.getCIntegerField("_frame_complete_offset");
|
frameCompleteOffsetField = type.getCIntegerField("_frame_complete_offset");
|
||||||
instructionsOffsetField = type.getCIntegerField("_instructions_offset");
|
contentOffsetField = type.getCIntegerField("_content_offset");
|
||||||
|
codeOffsetField = type.getCIntegerField("_code_offset");
|
||||||
dataOffsetField = type.getCIntegerField("_data_offset");
|
dataOffsetField = type.getCIntegerField("_data_offset");
|
||||||
frameSizeField = type.getCIntegerField("_frame_size");
|
frameSizeField = type.getCIntegerField("_frame_size");
|
||||||
oopMapsField = type.getAddressField("_oop_maps");
|
oopMapsField = type.getAddressField("_oop_maps");
|
||||||
@ -111,11 +113,19 @@ public class CodeBlob extends VMObject {
|
|||||||
// public RelocInfo relocationBegin();
|
// public RelocInfo relocationBegin();
|
||||||
// public RelocInfo relocationEnd();
|
// public RelocInfo relocationEnd();
|
||||||
|
|
||||||
public Address instructionsBegin() {
|
public Address contentBegin() {
|
||||||
return headerBegin().addOffsetTo(instructionsOffsetField.getValue(addr));
|
return headerBegin().addOffsetTo(contentOffsetField.getValue(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address instructionsEnd() {
|
public Address contentEnd() {
|
||||||
|
return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address codeBegin() {
|
||||||
|
return headerBegin().addOffsetTo(contentOffsetField.getValue(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address codeEnd() {
|
||||||
return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
|
return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,24 +138,27 @@ public class CodeBlob extends VMObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Offsets
|
// Offsets
|
||||||
public int getRelocationOffset() { return (int) headerSizeField.getValue(addr); }
|
public int getRelocationOffset() { return (int) headerSizeField .getValue(addr); }
|
||||||
public int getInstructionsOffset() { return (int) instructionsOffsetField.getValue(addr); }
|
public int getContentOffset() { return (int) contentOffsetField.getValue(addr); }
|
||||||
public int getDataOffset() { return (int) dataOffsetField.getValue(addr); }
|
public int getCodeOffset() { return (int) codeOffsetField .getValue(addr); }
|
||||||
|
public int getDataOffset() { return (int) dataOffsetField .getValue(addr); }
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
public int getSize() { return (int) sizeField.getValue(addr); }
|
public int getSize() { return (int) sizeField .getValue(addr); }
|
||||||
public int getHeaderSize() { return (int) headerSizeField.getValue(addr); }
|
public int getHeaderSize() { return (int) headerSizeField.getValue(addr); }
|
||||||
// FIXME: add getRelocationSize()
|
// FIXME: add getRelocationSize()
|
||||||
public int getInstructionsSize() { return (int) instructionsEnd().minus(instructionsBegin()); }
|
public int getContentSize() { return (int) contentEnd().minus(contentBegin()); }
|
||||||
public int getDataSize() { return (int) dataEnd().minus(dataBegin()); }
|
public int getCodeSize() { return (int) codeEnd() .minus(codeBegin()); }
|
||||||
|
public int getDataSize() { return (int) dataEnd() .minus(dataBegin()); }
|
||||||
|
|
||||||
// Containment
|
// Containment
|
||||||
public boolean blobContains(Address addr) { return headerBegin().lessThanOrEqual(addr) && dataEnd().greaterThan(addr); }
|
public boolean blobContains(Address addr) { return headerBegin() .lessThanOrEqual(addr) && dataEnd() .greaterThan(addr); }
|
||||||
// FIXME: add relocationContains
|
// FIXME: add relocationContains
|
||||||
public boolean instructionsContains(Address addr) { return instructionsBegin().lessThanOrEqual(addr) && instructionsEnd().greaterThan(addr); }
|
public boolean contentContains(Address addr) { return contentBegin().lessThanOrEqual(addr) && contentEnd().greaterThan(addr); }
|
||||||
public boolean dataContains(Address addr) { return dataBegin().lessThanOrEqual(addr) && dataEnd().greaterThan(addr); }
|
public boolean codeContains(Address addr) { return codeBegin() .lessThanOrEqual(addr) && codeEnd() .greaterThan(addr); }
|
||||||
public boolean contains(Address addr) { return instructionsContains(addr); }
|
public boolean dataContains(Address addr) { return dataBegin() .lessThanOrEqual(addr) && dataEnd() .greaterThan(addr); }
|
||||||
public boolean isFrameCompleteAt(Address a) { return instructionsContains(a) && a.minus(instructionsBegin()) >= frameCompleteOffsetField.getValue(addr); }
|
public boolean contains(Address addr) { return contentContains(addr); }
|
||||||
|
public boolean isFrameCompleteAt(Address a) { return codeContains(a) && a.minus(codeBegin()) >= frameCompleteOffsetField.getValue(addr); }
|
||||||
|
|
||||||
// Reclamation support (really only used by the nmethods, but in order to get asserts to work
|
// Reclamation support (really only used by the nmethods, but in order to get asserts to work
|
||||||
// in the CodeCache they are defined virtual here)
|
// in the CodeCache they are defined virtual here)
|
||||||
@ -168,7 +181,7 @@ public class CodeBlob extends VMObject {
|
|||||||
if (Assert.ASSERTS_ENABLED) {
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
Assert.that(getOopMaps() != null, "nope");
|
Assert.that(getOopMaps() != null, "nope");
|
||||||
}
|
}
|
||||||
return getOopMaps().findMapAtOffset(pc.minus(instructionsBegin()), debugging);
|
return getOopMaps().findMapAtOffset(pc.minus(codeBegin()), debugging);
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, void f(oop*)) { ShouldNotReachHere(); }
|
// virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, void f(oop*)) { ShouldNotReachHere(); }
|
||||||
@ -200,7 +213,8 @@ public class CodeBlob extends VMObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void printComponentsOn(PrintStream tty) {
|
protected void printComponentsOn(PrintStream tty) {
|
||||||
tty.println(" instructions: [" + instructionsBegin() + ", " + instructionsEnd() + "), " +
|
tty.println(" content: [" + contentBegin() + ", " + contentEnd() + "), " +
|
||||||
|
" code: [" + codeBegin() + ", " + codeEnd() + "), " +
|
||||||
" data: [" + dataBegin() + ", " + dataEnd() + "), " +
|
" data: [" + dataBegin() + ", " + dataEnd() + "), " +
|
||||||
" frame size: " + getFrameSize());
|
" frame size: " + getFrameSize());
|
||||||
}
|
}
|
||||||
|
@ -134,10 +134,10 @@ public class NMethod extends CodeBlob {
|
|||||||
public boolean isOSRMethod() { return getEntryBCI() != VM.getVM().getInvocationEntryBCI(); }
|
public boolean isOSRMethod() { return getEntryBCI() != VM.getVM().getInvocationEntryBCI(); }
|
||||||
|
|
||||||
/** Boundaries for different parts */
|
/** Boundaries for different parts */
|
||||||
public Address constantsBegin() { return instructionsBegin(); }
|
public Address constantsBegin() { return contentBegin(); }
|
||||||
public Address constantsEnd() { return getEntryPoint(); }
|
public Address constantsEnd() { return getEntryPoint(); }
|
||||||
public Address codeBegin() { return getEntryPoint(); }
|
public Address instsBegin() { return codeBegin(); }
|
||||||
public Address codeEnd() { return headerBegin().addOffsetTo(getStubOffset()); }
|
public Address instsEnd() { return headerBegin().addOffsetTo(getStubOffset()); }
|
||||||
public Address exceptionBegin() { return headerBegin().addOffsetTo(getExceptionOffset()); }
|
public Address exceptionBegin() { return headerBegin().addOffsetTo(getExceptionOffset()); }
|
||||||
public Address deoptBegin() { return headerBegin().addOffsetTo(getDeoptOffset()); }
|
public Address deoptBegin() { return headerBegin().addOffsetTo(getDeoptOffset()); }
|
||||||
public Address stubBegin() { return headerBegin().addOffsetTo(getStubOffset()); }
|
public Address stubBegin() { return headerBegin().addOffsetTo(getStubOffset()); }
|
||||||
@ -156,7 +156,7 @@ public class NMethod extends CodeBlob {
|
|||||||
public Address nulChkTableEnd() { return headerBegin().addOffsetTo(getNMethodEndOffset()); }
|
public Address nulChkTableEnd() { return headerBegin().addOffsetTo(getNMethodEndOffset()); }
|
||||||
|
|
||||||
public int constantsSize() { return (int) constantsEnd() .minus(constantsBegin()); }
|
public int constantsSize() { return (int) constantsEnd() .minus(constantsBegin()); }
|
||||||
public int codeSize() { return (int) codeEnd() .minus(codeBegin()); }
|
public int instsSize() { return (int) instsEnd() .minus(instsBegin()); }
|
||||||
public int stubSize() { return (int) stubEnd() .minus(stubBegin()); }
|
public int stubSize() { return (int) stubEnd() .minus(stubBegin()); }
|
||||||
public int oopsSize() { return (int) oopsEnd() .minus(oopsBegin()); }
|
public int oopsSize() { return (int) oopsEnd() .minus(oopsBegin()); }
|
||||||
public int scopesDataSize() { return (int) scopesDataEnd() .minus(scopesDataBegin()); }
|
public int scopesDataSize() { return (int) scopesDataEnd() .minus(scopesDataBegin()); }
|
||||||
@ -169,7 +169,7 @@ public class NMethod extends CodeBlob {
|
|||||||
public int totalSize() {
|
public int totalSize() {
|
||||||
return
|
return
|
||||||
constantsSize() +
|
constantsSize() +
|
||||||
codeSize() +
|
instsSize() +
|
||||||
stubSize() +
|
stubSize() +
|
||||||
scopesDataSize() +
|
scopesDataSize() +
|
||||||
scopesPCsSize() +
|
scopesPCsSize() +
|
||||||
@ -179,7 +179,7 @@ public class NMethod extends CodeBlob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean constantsContains (Address addr) { return constantsBegin() .lessThanOrEqual(addr) && constantsEnd() .greaterThan(addr); }
|
public boolean constantsContains (Address addr) { return constantsBegin() .lessThanOrEqual(addr) && constantsEnd() .greaterThan(addr); }
|
||||||
public boolean codeContains (Address addr) { return codeBegin() .lessThanOrEqual(addr) && codeEnd() .greaterThan(addr); }
|
public boolean instsContains (Address addr) { return instsBegin() .lessThanOrEqual(addr) && instsEnd() .greaterThan(addr); }
|
||||||
public boolean stubContains (Address addr) { return stubBegin() .lessThanOrEqual(addr) && stubEnd() .greaterThan(addr); }
|
public boolean stubContains (Address addr) { return stubBegin() .lessThanOrEqual(addr) && stubEnd() .greaterThan(addr); }
|
||||||
public boolean oopsContains (Address addr) { return oopsBegin() .lessThanOrEqual(addr) && oopsEnd() .greaterThan(addr); }
|
public boolean oopsContains (Address addr) { return oopsBegin() .lessThanOrEqual(addr) && oopsEnd() .greaterThan(addr); }
|
||||||
public boolean scopesDataContains (Address addr) { return scopesDataBegin() .lessThanOrEqual(addr) && scopesDataEnd() .greaterThan(addr); }
|
public boolean scopesDataContains (Address addr) { return scopesDataBegin() .lessThanOrEqual(addr) && scopesDataEnd() .greaterThan(addr); }
|
||||||
@ -353,7 +353,8 @@ public class NMethod extends CodeBlob {
|
|||||||
|
|
||||||
protected void printComponentsOn(PrintStream tty) {
|
protected void printComponentsOn(PrintStream tty) {
|
||||||
// FIXME: add relocation information
|
// FIXME: add relocation information
|
||||||
tty.println(" instructions: [" + instructionsBegin() + ", " + instructionsEnd() + "), " +
|
tty.println(" content: [" + contentBegin() + ", " + contentEnd() + "), " +
|
||||||
|
" code: [" + codeBegin() + ", " + codeEnd() + "), " +
|
||||||
" data: [" + dataBegin() + ", " + dataEnd() + "), " +
|
" data: [" + dataBegin() + ", " + dataEnd() + "), " +
|
||||||
" oops: [" + oopsBegin() + ", " + oopsEnd() + "), " +
|
" oops: [" + oopsBegin() + ", " + oopsEnd() + "), " +
|
||||||
" frame size: " + getFrameSize());
|
" frame size: " + getFrameSize());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -75,7 +75,7 @@ public class PCDesc extends VMObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Address getRealPC(NMethod code) {
|
public Address getRealPC(NMethod code) {
|
||||||
return code.instructionsBegin().addOffsetTo(getPCOffset());
|
return code.codeBegin().addOffsetTo(getPCOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -190,11 +190,11 @@ public class FindInCodeCachePanel extends SAPanel {
|
|||||||
|
|
||||||
private void reportResult(StringBuffer result, CodeBlob blob) {
|
private void reportResult(StringBuffer result, CodeBlob blob) {
|
||||||
result.append("<a href='blob:");
|
result.append("<a href='blob:");
|
||||||
result.append(blob.instructionsBegin().toString());
|
result.append(blob.contentBegin().toString());
|
||||||
result.append("'>");
|
result.append("'>");
|
||||||
result.append(blob.getName());
|
result.append(blob.getName());
|
||||||
result.append("@");
|
result.append("@");
|
||||||
result.append(blob.instructionsBegin());
|
result.append(blob.contentBegin());
|
||||||
result.append("</a><br>");
|
result.append("</a><br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1415,13 +1415,13 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
|||||||
buf.append(genMethodAndKlassLink(nmethod.getMethod()));
|
buf.append(genMethodAndKlassLink(nmethod.getMethod()));
|
||||||
|
|
||||||
buf.h3("Compiled Code");
|
buf.h3("Compiled Code");
|
||||||
sun.jvm.hotspot.debugger.Address codeBegin = nmethod.codeBegin();
|
sun.jvm.hotspot.debugger.Address instsBegin = nmethod.instsBegin();
|
||||||
sun.jvm.hotspot.debugger.Address codeEnd = nmethod.codeEnd();
|
sun.jvm.hotspot.debugger.Address instsEnd = nmethod.instsEnd();
|
||||||
final int codeSize = (int)codeEnd.minus(codeBegin);
|
final int instsSize = nmethod.instsSize();
|
||||||
final long startPc = addressToLong(codeBegin);
|
final long startPc = addressToLong(instsBegin);
|
||||||
final byte[] code = new byte[codeSize];
|
final byte[] code = new byte[instsSize];
|
||||||
for (int i=0; i < code.length; i++)
|
for (int i=0; i < code.length; i++)
|
||||||
code[i] = codeBegin.getJByteAt(i);
|
code[i] = instsBegin.getJByteAt(i);
|
||||||
|
|
||||||
final long verifiedEntryPoint = addressToLong(nmethod.getVerifiedEntryPoint());
|
final long verifiedEntryPoint = addressToLong(nmethod.getVerifiedEntryPoint());
|
||||||
final long entryPoint = addressToLong(nmethod.getEntryPoint());
|
final long entryPoint = addressToLong(nmethod.getEntryPoint());
|
||||||
@ -1499,8 +1499,8 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
|||||||
buf.h3("CodeBlob");
|
buf.h3("CodeBlob");
|
||||||
|
|
||||||
buf.h3("Compiled Code");
|
buf.h3("Compiled Code");
|
||||||
final sun.jvm.hotspot.debugger.Address codeBegin = blob.instructionsBegin();
|
final sun.jvm.hotspot.debugger.Address codeBegin = blob.codeBegin();
|
||||||
final int codeSize = blob.getInstructionsSize();
|
final int codeSize = blob.getCodeSize();
|
||||||
final long startPc = addressToLong(codeBegin);
|
final long startPc = addressToLong(codeBegin);
|
||||||
final byte[] code = new byte[codeSize];
|
final byte[] code = new byte[codeSize];
|
||||||
for (int i=0; i < code.length; i++)
|
for (int i=0; i < code.length; i++)
|
||||||
|
@ -96,15 +96,15 @@ public class PointerFinder {
|
|||||||
if (Assert.ASSERTS_ENABLED) {
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
Assert.that(loc.blob != null, "Should have found CodeBlob");
|
Assert.that(loc.blob != null, "Should have found CodeBlob");
|
||||||
}
|
}
|
||||||
loc.inBlobInstructions = loc.blob.instructionsContains(a);
|
loc.inBlobCode = loc.blob.codeContains(a);
|
||||||
loc.inBlobData = loc.blob.dataContains(a);
|
loc.inBlobData = loc.blob.dataContains(a);
|
||||||
|
|
||||||
if (loc.blob.isNMethod()) {
|
if (loc.blob.isNMethod()) {
|
||||||
NMethod nm = (NMethod) loc.blob;
|
NMethod nm = (NMethod) loc.blob;
|
||||||
loc.inBlobOops = nm.oopsContains(a);
|
loc.inBlobOops = nm.oopsContains(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
loc.inBlobUnknownLocation = (!(loc.inBlobInstructions ||
|
loc.inBlobUnknownLocation = (!(loc.inBlobCode ||
|
||||||
loc.inBlobData ||
|
loc.inBlobData ||
|
||||||
loc.inBlobOops));
|
loc.inBlobOops));
|
||||||
return loc;
|
return loc;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -65,7 +65,7 @@ public class PointerLocation {
|
|||||||
InterpreterCodelet interpreterCodelet;
|
InterpreterCodelet interpreterCodelet;
|
||||||
CodeBlob blob;
|
CodeBlob blob;
|
||||||
// FIXME: add more detail about CodeBlob
|
// FIXME: add more detail about CodeBlob
|
||||||
boolean inBlobInstructions;
|
boolean inBlobCode;
|
||||||
boolean inBlobData;
|
boolean inBlobData;
|
||||||
boolean inBlobOops;
|
boolean inBlobOops;
|
||||||
boolean inBlobUnknownLocation;
|
boolean inBlobUnknownLocation;
|
||||||
@ -142,8 +142,8 @@ public class PointerLocation {
|
|||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInBlobInstructions() {
|
public boolean isInBlobCode() {
|
||||||
return inBlobInstructions;
|
return inBlobCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInBlobData() {
|
public boolean isInBlobData() {
|
||||||
@ -233,8 +233,8 @@ public class PointerLocation {
|
|||||||
} else if (isInCodeCache()) {
|
} else if (isInCodeCache()) {
|
||||||
CodeBlob b = getCodeBlob();
|
CodeBlob b = getCodeBlob();
|
||||||
tty.print("In ");
|
tty.print("In ");
|
||||||
if (isInBlobInstructions()) {
|
if (isInBlobCode()) {
|
||||||
tty.print("instructions");
|
tty.print("code");
|
||||||
} else if (isInBlobData()) {
|
} else if (isInBlobData()) {
|
||||||
tty.print("data");
|
tty.print("data");
|
||||||
} else if (isInBlobOops()) {
|
} else if (isInBlobOops()) {
|
||||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2010
|
|||||||
|
|
||||||
HS_MAJOR_VER=19
|
HS_MAJOR_VER=19
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=07
|
HS_BUILD_NUMBER=06
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=7
|
JDK_MINOR_VER=7
|
||||||
|
@ -4192,7 +4192,7 @@ static void check_index(int ind) {
|
|||||||
|
|
||||||
static void generate_satb_log_enqueue(bool with_frame) {
|
static void generate_satb_log_enqueue(bool with_frame) {
|
||||||
BufferBlob* bb = BufferBlob::create("enqueue_with_frame", EnqueueCodeSize);
|
BufferBlob* bb = BufferBlob::create("enqueue_with_frame", EnqueueCodeSize);
|
||||||
CodeBuffer buf(bb->instructions_begin(), bb->instructions_size());
|
CodeBuffer buf(bb);
|
||||||
MacroAssembler masm(&buf);
|
MacroAssembler masm(&buf);
|
||||||
address start = masm.pc();
|
address start = masm.pc();
|
||||||
Register pre_val;
|
Register pre_val;
|
||||||
@ -4421,7 +4421,7 @@ static u_char* dirty_card_log_enqueue_end = 0;
|
|||||||
// This gets to assume that o0 contains the object address.
|
// This gets to assume that o0 contains the object address.
|
||||||
static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
|
static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
|
||||||
BufferBlob* bb = BufferBlob::create("dirty_card_enqueue", EnqueueCodeSize*2);
|
BufferBlob* bb = BufferBlob::create("dirty_card_enqueue", EnqueueCodeSize*2);
|
||||||
CodeBuffer buf(bb->instructions_begin(), bb->instructions_size());
|
CodeBuffer buf(bb);
|
||||||
MacroAssembler masm(&buf);
|
MacroAssembler masm(&buf);
|
||||||
address start = masm.pc();
|
address start = masm.pc();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,5 +30,5 @@ public:
|
|||||||
|
|
||||||
// Heuristic for pre-packing the pt/pn bit of a predicted branch.
|
// Heuristic for pre-packing the pt/pn bit of a predicted branch.
|
||||||
bool is_backward_branch(Label& L) {
|
bool is_backward_branch(Label& L) {
|
||||||
return L.is_bound() && code_end() <= locator_address(L.loc());
|
return L.is_bound() && insts_end() <= locator_address(L.loc());
|
||||||
}
|
}
|
||||||
|
@ -253,11 +253,12 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Could just be some random pointer within the codeBlob
|
// Could just be some random pointer within the codeBlob
|
||||||
if (!sender.cb()->instructions_contains(sender_pc)) return false;
|
if (!sender.cb()->code_contains(sender_pc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// We should never be able to see an adapter if the current frame is something from code cache
|
// We should never be able to see an adapter if the current frame is something from code cache
|
||||||
|
if (sender_blob->is_adapter_blob()) {
|
||||||
if ( sender_blob->is_adapter_blob()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -50,10 +50,10 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
|
|||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label label1, label2;
|
Label label1, label2;
|
||||||
|
|
||||||
@ -129,10 +129,10 @@ address JNI_FastGetField::generate_fast_get_int_field() {
|
|||||||
address JNI_FastGetField::generate_fast_get_long_field() {
|
address JNI_FastGetField::generate_fast_get_long_field() {
|
||||||
const char *name = "jni_fast_GetLongField";
|
const char *name = "jni_fast_GetLongField";
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label label1, label2;
|
Label label1, label2;
|
||||||
|
|
||||||
@ -201,10 +201,10 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
|
|||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label label1, label2;
|
Label label1, label2;
|
||||||
|
|
||||||
|
@ -193,17 +193,17 @@ void NativeCall::test() {
|
|||||||
|
|
||||||
a->call( a->pc(), relocInfo::none );
|
a->call( a->pc(), relocInfo::none );
|
||||||
a->delayed()->nop();
|
a->delayed()->nop();
|
||||||
nc = nativeCall_at( cb.code_begin() );
|
nc = nativeCall_at( cb.insts_begin() );
|
||||||
nc->print();
|
nc->print();
|
||||||
|
|
||||||
nc = nativeCall_overwriting_at( nc->next_instruction_address() );
|
nc = nativeCall_overwriting_at( nc->next_instruction_address() );
|
||||||
for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
|
for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
|
||||||
nc->set_destination( cb.code_begin() + offsets[idx] );
|
nc->set_destination( cb.insts_begin() + offsets[idx] );
|
||||||
assert(nc->destination() == (cb.code_begin() + offsets[idx]), "check unit test");
|
assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
|
||||||
nc->print();
|
nc->print();
|
||||||
}
|
}
|
||||||
|
|
||||||
nc = nativeCall_before( cb.code_begin() + 8 );
|
nc = nativeCall_before( cb.insts_begin() + 8 );
|
||||||
nc->print();
|
nc->print();
|
||||||
|
|
||||||
VM_Version::revert();
|
VM_Version::revert();
|
||||||
@ -368,7 +368,7 @@ void NativeMovConstReg::test() {
|
|||||||
a->sethi(al2, O2);
|
a->sethi(al2, O2);
|
||||||
a->add(O2, al2.low10(), O2);
|
a->add(O2, al2.low10(), O2);
|
||||||
|
|
||||||
nm = nativeMovConstReg_at( cb.code_begin() );
|
nm = nativeMovConstReg_at( cb.insts_begin() );
|
||||||
nm->print();
|
nm->print();
|
||||||
|
|
||||||
nm = nativeMovConstReg_at( nm->next_instruction_address() );
|
nm = nativeMovConstReg_at( nm->next_instruction_address() );
|
||||||
@ -480,7 +480,7 @@ void NativeMovConstRegPatching::test() {
|
|||||||
a->nop();
|
a->nop();
|
||||||
a->add(O2, al2.low10(), O2);
|
a->add(O2, al2.low10(), O2);
|
||||||
|
|
||||||
nm = nativeMovConstRegPatching_at( cb.code_begin() );
|
nm = nativeMovConstRegPatching_at( cb.insts_begin() );
|
||||||
nm->print();
|
nm->print();
|
||||||
|
|
||||||
nm = nativeMovConstRegPatching_at( nm->next_instruction_address() );
|
nm = nativeMovConstRegPatching_at( nm->next_instruction_address() );
|
||||||
@ -616,7 +616,7 @@ void NativeMovRegMem::test() {
|
|||||||
a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
|
a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
|
||||||
a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++;
|
a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++;
|
||||||
|
|
||||||
nm = nativeMovRegMem_at( cb.code_begin() );
|
nm = nativeMovRegMem_at( cb.insts_begin() );
|
||||||
nm->print();
|
nm->print();
|
||||||
nm->set_offset( low10(0) );
|
nm->set_offset( low10(0) );
|
||||||
nm->print();
|
nm->print();
|
||||||
@ -760,7 +760,7 @@ void NativeMovRegMemPatching::test() {
|
|||||||
a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
|
a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
|
||||||
a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++;
|
a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++;
|
||||||
|
|
||||||
nm = nativeMovRegMemPatching_at( cb.code_begin() );
|
nm = nativeMovRegMemPatching_at( cb.insts_begin() );
|
||||||
nm->print();
|
nm->print();
|
||||||
nm->set_offset( low10(0) );
|
nm->set_offset( low10(0) );
|
||||||
nm->print();
|
nm->print();
|
||||||
@ -849,7 +849,7 @@ void NativeJump::test() {
|
|||||||
a->jmpl(I3, al.low10(), L3, RelocationHolder::none);
|
a->jmpl(I3, al.low10(), L3, RelocationHolder::none);
|
||||||
a->delayed()->nop();
|
a->delayed()->nop();
|
||||||
|
|
||||||
nj = nativeJump_at( cb.code_begin() );
|
nj = nativeJump_at( cb.insts_begin() );
|
||||||
nj->print();
|
nj->print();
|
||||||
|
|
||||||
nj = nativeJump_at( nj->next_instruction_address() );
|
nj = nativeJump_at( nj->next_instruction_address() );
|
||||||
|
@ -677,8 +677,7 @@ static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22
|
|||||||
(f20 << 20) |
|
(f20 << 20) |
|
||||||
(f19 << 19) |
|
(f19 << 19) |
|
||||||
(f0 << 0);
|
(f0 << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standard Sparc opcode form2 field breakdown
|
// Standard Sparc opcode form2 field breakdown
|
||||||
@ -689,8 +688,7 @@ static inline void emit2_22(CodeBuffer &cbuf, int f30, int f25, int f22, int f0
|
|||||||
(f25 << 25) |
|
(f25 << 25) |
|
||||||
(f22 << 22) |
|
(f22 << 22) |
|
||||||
(f0 << 0);
|
(f0 << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standard Sparc opcode form3 field breakdown
|
// Standard Sparc opcode form3 field breakdown
|
||||||
@ -701,8 +699,7 @@ static inline void emit3(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, i
|
|||||||
(f14 << 14) |
|
(f14 << 14) |
|
||||||
(f5 << 5) |
|
(f5 << 5) |
|
||||||
(f0 << 0);
|
(f0 << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standard Sparc opcode form3 field breakdown
|
// Standard Sparc opcode form3 field breakdown
|
||||||
@ -714,8 +711,7 @@ static inline void emit3_simm13(CodeBuffer &cbuf, int f30, int f25, int f19, int
|
|||||||
(f14 << 14) |
|
(f14 << 14) |
|
||||||
(1 << 13) | // bit to indicate immediate-mode
|
(1 << 13) | // bit to indicate immediate-mode
|
||||||
(simm13<<0);
|
(simm13<<0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void emit3_simm10(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int simm10 ) {
|
static inline void emit3_simm10(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int simm10 ) {
|
||||||
@ -910,9 +906,7 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, const MachNode* n, int primary, int te
|
|||||||
instr |= disp & 0x1FFF;
|
instr |= disp & 0x1FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint *code = (uint*)cbuf.code_end();
|
cbuf.insts()->emit_int32(instr);
|
||||||
*code = instr;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
{
|
{
|
||||||
@ -1532,7 +1526,7 @@ void emit_java_to_interp(CodeBuffer &cbuf ) {
|
|||||||
// set (empty), G5
|
// set (empty), G5
|
||||||
// jmp -1
|
// jmp -1
|
||||||
|
|
||||||
address mark = cbuf.inst_mark(); // get mark within main instrs section
|
address mark = cbuf.insts_mark(); // get mark within main instrs section
|
||||||
|
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
|
|
||||||
@ -1632,7 +1626,7 @@ uint size_deopt_handler() {
|
|||||||
// Emit exception handler code.
|
// Emit exception handler code.
|
||||||
int emit_exception_handler(CodeBuffer& cbuf) {
|
int emit_exception_handler(CodeBuffer& cbuf) {
|
||||||
Register temp_reg = G3;
|
Register temp_reg = G3;
|
||||||
AddressLiteral exception_blob(OptoRuntime::exception_blob()->instructions_begin());
|
AddressLiteral exception_blob(OptoRuntime::exception_blob()->entry_point());
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
|
|
||||||
address base =
|
address base =
|
||||||
@ -2292,8 +2286,7 @@ encode %{
|
|||||||
(0 << 13) | // select register move
|
(0 << 13) | // select register move
|
||||||
($pcc$$constant << 11) | // cc1, cc0 bits for 'icc' or 'xcc'
|
($pcc$$constant << 11) | // cc1, cc0 bits for 'icc' or 'xcc'
|
||||||
($src$$reg << 0);
|
($src$$reg << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cmov_imm( cmpOp cmp, iRegI dst, immI11 src, immI pcc ) %{
|
enc_class enc_cmov_imm( cmpOp cmp, iRegI dst, immI11 src, immI pcc ) %{
|
||||||
@ -2306,8 +2299,7 @@ encode %{
|
|||||||
(1 << 13) | // select immediate move
|
(1 << 13) | // select immediate move
|
||||||
($pcc$$constant << 11) | // cc1, cc0 bits for 'icc'
|
($pcc$$constant << 11) | // cc1, cc0 bits for 'icc'
|
||||||
(simm11 << 0);
|
(simm11 << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cmov_reg_f( cmpOpF cmp, iRegI dst, iRegI src, flagsRegF fcc ) %{
|
enc_class enc_cmov_reg_f( cmpOpF cmp, iRegI dst, iRegI src, flagsRegF fcc ) %{
|
||||||
@ -2319,8 +2311,7 @@ encode %{
|
|||||||
(0 << 13) | // select register move
|
(0 << 13) | // select register move
|
||||||
($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3
|
($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3
|
||||||
($src$$reg << 0);
|
($src$$reg << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cmov_imm_f( cmpOp cmp, iRegI dst, immI11 src, flagsRegF fcc ) %{
|
enc_class enc_cmov_imm_f( cmpOp cmp, iRegI dst, immI11 src, flagsRegF fcc ) %{
|
||||||
@ -2333,8 +2324,7 @@ encode %{
|
|||||||
(1 << 13) | // select immediate move
|
(1 << 13) | // select immediate move
|
||||||
($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3
|
($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3
|
||||||
(simm11 << 0);
|
(simm11 << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cmovf_reg( cmpOp cmp, regD dst, regD src, immI pcc ) %{
|
enc_class enc_cmovf_reg( cmpOp cmp, regD dst, regD src, immI pcc ) %{
|
||||||
@ -2347,8 +2337,7 @@ encode %{
|
|||||||
($pcc$$constant << 11) | // cc1-cc0 bits for 'icc' or 'xcc'
|
($pcc$$constant << 11) | // cc1-cc0 bits for 'icc' or 'xcc'
|
||||||
($primary << 5) | // select single, double or quad
|
($primary << 5) | // select single, double or quad
|
||||||
($src$$reg << 0);
|
($src$$reg << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cmovff_reg( cmpOpF cmp, flagsRegF fcc, regD dst, regD src ) %{
|
enc_class enc_cmovff_reg( cmpOpF cmp, flagsRegF fcc, regD dst, regD src ) %{
|
||||||
@ -2360,8 +2349,7 @@ encode %{
|
|||||||
($fcc$$reg << 11) | // cc2-cc0 bits for 'fccX'
|
($fcc$$reg << 11) | // cc2-cc0 bits for 'fccX'
|
||||||
($primary << 5) | // select single, double or quad
|
($primary << 5) | // select single, double or quad
|
||||||
($src$$reg << 0);
|
($src$$reg << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Used by the MIN/MAX encodings. Same as a CMOV, but
|
// Used by the MIN/MAX encodings. Same as a CMOV, but
|
||||||
@ -2375,8 +2363,7 @@ encode %{
|
|||||||
(0 << 13) | // select register move
|
(0 << 13) | // select register move
|
||||||
(0 << 11) | // cc1, cc0 bits for 'icc'
|
(0 << 11) | // cc1, cc0 bits for 'icc'
|
||||||
($src$$reg << 0);
|
($src$$reg << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cmov_reg_minmax_long( iRegL dst, iRegL src ) %{
|
enc_class enc_cmov_reg_minmax_long( iRegL dst, iRegL src ) %{
|
||||||
@ -2388,8 +2375,7 @@ encode %{
|
|||||||
(0 << 13) | // select register move
|
(0 << 13) | // select register move
|
||||||
(0 << 11) | // cc1, cc0 bits for 'icc'
|
(0 << 11) | // cc1, cc0 bits for 'icc'
|
||||||
($src$$reg << 0);
|
($src$$reg << 0);
|
||||||
*((int*)(cbuf.code_end())) = op;
|
cbuf.insts()->emit_int32(op);
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Utility encoding for loading a 64 bit Pointer into a register
|
// Utility encoding for loading a 64 bit Pointer into a register
|
||||||
@ -3055,7 +3041,7 @@ enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI r
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_rethrow() %{
|
enc_class enc_rethrow() %{
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
Register temp_reg = G3;
|
Register temp_reg = G3;
|
||||||
AddressLiteral rethrow_stub(OptoRuntime::rethrow_stub());
|
AddressLiteral rethrow_stub(OptoRuntime::rethrow_stub());
|
||||||
assert(temp_reg != reg_to_register_object(R_I0_num), "temp must not break oop_reg");
|
assert(temp_reg != reg_to_register_object(R_I0_num), "temp must not break oop_reg");
|
||||||
@ -3076,23 +3062,17 @@ enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI r
|
|||||||
|
|
||||||
enc_class emit_mem_nop() %{
|
enc_class emit_mem_nop() %{
|
||||||
// Generates the instruction LDUXA [o6,g0],#0x82,g0
|
// Generates the instruction LDUXA [o6,g0],#0x82,g0
|
||||||
unsigned int *code = (unsigned int*)cbuf.code_end();
|
cbuf.insts()->emit_int32((unsigned int) 0xc0839040);
|
||||||
*code = (unsigned int)0xc0839040;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class emit_fadd_nop() %{
|
enc_class emit_fadd_nop() %{
|
||||||
// Generates the instruction FMOVS f31,f31
|
// Generates the instruction FMOVS f31,f31
|
||||||
unsigned int *code = (unsigned int*)cbuf.code_end();
|
cbuf.insts()->emit_int32((unsigned int) 0xbfa0003f);
|
||||||
*code = (unsigned int)0xbfa0003f;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class emit_br_nop() %{
|
enc_class emit_br_nop() %{
|
||||||
// Generates the instruction BPN,PN .
|
// Generates the instruction BPN,PN .
|
||||||
unsigned int *code = (unsigned int*)cbuf.code_end();
|
cbuf.insts()->emit_int32((unsigned int) 0x00400000);
|
||||||
*code = (unsigned int)0x00400000;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_membar_acquire %{
|
enc_class enc_membar_acquire %{
|
||||||
|
@ -141,12 +141,12 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Could just be some random pointer within the codeBlob
|
// Could just be some random pointer within the codeBlob
|
||||||
|
if (!sender_blob->code_contains(sender_pc)) {
|
||||||
if (!sender_blob->instructions_contains(sender_pc)) return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// We should never be able to see an adapter if the current frame is something from code cache
|
// We should never be able to see an adapter if the current frame is something from code cache
|
||||||
|
if (sender_blob->is_adapter_blob()) {
|
||||||
if ( sender_blob->is_adapter_blob()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool
|
|||||||
fr._unextended_sp = unextended_sp;
|
fr._unextended_sp = unextended_sp;
|
||||||
|
|
||||||
address original_pc = nm->get_original_pc(&fr);
|
address original_pc = nm->get_original_pc(&fr);
|
||||||
assert(nm->code_contains(original_pc), "original PC must be in nmethod");
|
assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
|
||||||
assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
|
assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,7 +63,7 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address
|
|||||||
address original_pc = nmethod::get_deopt_original_pc(this);
|
address original_pc = nmethod::get_deopt_original_pc(this);
|
||||||
if (original_pc != NULL) {
|
if (original_pc != NULL) {
|
||||||
_pc = original_pc;
|
_pc = original_pc;
|
||||||
assert(((nmethod*)_cb)->code_contains(_pc), "original PC must be in nmethod");
|
assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod");
|
||||||
_deopt_state = is_deoptimized;
|
_deopt_state = is_deoptimized;
|
||||||
} else {
|
} else {
|
||||||
_deopt_state = not_deoptimized;
|
_deopt_state = not_deoptimized;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -54,10 +54,10 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
|
|||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label slow;
|
Label slow;
|
||||||
|
|
||||||
@ -135,11 +135,11 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
|
|||||||
return fast_entry;
|
return fast_entry;
|
||||||
#else
|
#else
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case T_BOOLEAN: jni_fast_GetBooleanField_fp = (GetBooleanField_t)fast_entry; break;
|
case T_BOOLEAN: jni_fast_GetBooleanField_fp = (GetBooleanField_t) fast_entry; break;
|
||||||
case T_BYTE: jni_fast_GetByteField_fp = (GetByteField_t)fast_entry; break;
|
case T_BYTE: jni_fast_GetByteField_fp = (GetByteField_t) fast_entry; break;
|
||||||
case T_CHAR: jni_fast_GetCharField_fp = (GetCharField_t)fast_entry; break;
|
case T_CHAR: jni_fast_GetCharField_fp = (GetCharField_t) fast_entry; break;
|
||||||
case T_SHORT: jni_fast_GetShortField_fp = (GetShortField_t)fast_entry; break;
|
case T_SHORT: jni_fast_GetShortField_fp = (GetShortField_t) fast_entry; break;
|
||||||
case T_INT: jni_fast_GetIntField_fp = (GetIntField_t)fast_entry;
|
case T_INT: jni_fast_GetIntField_fp = (GetIntField_t) fast_entry; break;
|
||||||
}
|
}
|
||||||
return os::win32::fast_jni_accessor_wrapper(type);
|
return os::win32::fast_jni_accessor_wrapper(type);
|
||||||
#endif
|
#endif
|
||||||
@ -168,10 +168,10 @@ address JNI_FastGetField::generate_fast_get_int_field() {
|
|||||||
address JNI_FastGetField::generate_fast_get_long_field() {
|
address JNI_FastGetField::generate_fast_get_long_field() {
|
||||||
const char *name = "jni_fast_GetLongField";
|
const char *name = "jni_fast_GetLongField";
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label slow;
|
Label slow;
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ address JNI_FastGetField::generate_fast_get_long_field() {
|
|||||||
#ifndef _WINDOWS
|
#ifndef _WINDOWS
|
||||||
return fast_entry;
|
return fast_entry;
|
||||||
#else
|
#else
|
||||||
jni_fast_GetLongField_fp = (GetLongField_t)fast_entry;
|
jni_fast_GetLongField_fp = (GetLongField_t) fast_entry;
|
||||||
return os::win32::fast_jni_accessor_wrapper(T_LONG);
|
return os::win32::fast_jni_accessor_wrapper(T_LONG);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -259,10 +259,10 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
|
|||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label slow_with_pop, slow;
|
Label slow_with_pop, slow;
|
||||||
|
|
||||||
@ -348,8 +348,8 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
|
|||||||
return fast_entry;
|
return fast_entry;
|
||||||
#else
|
#else
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case T_FLOAT: jni_fast_GetFloatField_fp = (GetFloatField_t)fast_entry; break;
|
case T_FLOAT: jni_fast_GetFloatField_fp = (GetFloatField_t) fast_entry; break;
|
||||||
case T_DOUBLE: jni_fast_GetDoubleField_fp = (GetDoubleField_t)fast_entry;
|
case T_DOUBLE: jni_fast_GetDoubleField_fp = (GetDoubleField_t) fast_entry; break;
|
||||||
}
|
}
|
||||||
return os::win32::fast_jni_accessor_wrapper(type);
|
return os::win32::fast_jni_accessor_wrapper(type);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -58,10 +58,10 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
|
|||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label slow;
|
Label slow;
|
||||||
|
|
||||||
@ -156,10 +156,10 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
|
|||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE);
|
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
|
||||||
address fast_entry = b->instructions_begin();
|
CodeBuffer cbuf(blob);
|
||||||
CodeBuffer cbuf(fast_entry, b->instructions_size());
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
||||||
|
address fast_entry = __ pc();
|
||||||
|
|
||||||
Label slow;
|
Label slow;
|
||||||
|
|
||||||
|
@ -595,8 +595,7 @@ void VM_Version::initialize() {
|
|||||||
if (stub_blob == NULL) {
|
if (stub_blob == NULL) {
|
||||||
vm_exit_during_initialization("Unable to allocate getPsrInfo_stub");
|
vm_exit_during_initialization("Unable to allocate getPsrInfo_stub");
|
||||||
}
|
}
|
||||||
CodeBuffer c(stub_blob->instructions_begin(),
|
CodeBuffer c(stub_blob);
|
||||||
stub_blob->instructions_size());
|
|
||||||
VM_Version_StubGenerator g(&c);
|
VM_Version_StubGenerator g(&c);
|
||||||
getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t,
|
getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t,
|
||||||
g.generate_getPsrInfo());
|
g.generate_getPsrInfo());
|
||||||
|
@ -350,54 +350,46 @@ void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
|
|||||||
// EMIT_RM()
|
// EMIT_RM()
|
||||||
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
||||||
unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3);
|
unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3);
|
||||||
*(cbuf.code_end()) = c;
|
cbuf.insts()->emit_int8(c);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_CC()
|
// EMIT_CC()
|
||||||
void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
|
void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
|
||||||
unsigned char c = (unsigned char)( f1 | f2 );
|
unsigned char c = (unsigned char)( f1 | f2 );
|
||||||
*(cbuf.code_end()) = c;
|
cbuf.insts()->emit_int8(c);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_OPCODE()
|
// EMIT_OPCODE()
|
||||||
void emit_opcode(CodeBuffer &cbuf, int code) {
|
void emit_opcode(CodeBuffer &cbuf, int code) {
|
||||||
*(cbuf.code_end()) = (unsigned char)code;
|
cbuf.insts()->emit_int8((unsigned char) code);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_OPCODE() w/ relocation information
|
// EMIT_OPCODE() w/ relocation information
|
||||||
void emit_opcode(CodeBuffer &cbuf, int code, relocInfo::relocType reloc, int offset = 0) {
|
void emit_opcode(CodeBuffer &cbuf, int code, relocInfo::relocType reloc, int offset = 0) {
|
||||||
cbuf.relocate(cbuf.inst_mark() + offset, reloc);
|
cbuf.relocate(cbuf.insts_mark() + offset, reloc);
|
||||||
emit_opcode(cbuf, code);
|
emit_opcode(cbuf, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D8()
|
// EMIT_D8()
|
||||||
void emit_d8(CodeBuffer &cbuf, int d8) {
|
void emit_d8(CodeBuffer &cbuf, int d8) {
|
||||||
*(cbuf.code_end()) = (unsigned char)d8;
|
cbuf.insts()->emit_int8((unsigned char) d8);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D16()
|
// EMIT_D16()
|
||||||
void emit_d16(CodeBuffer &cbuf, int d16) {
|
void emit_d16(CodeBuffer &cbuf, int d16) {
|
||||||
*((short *)(cbuf.code_end())) = d16;
|
cbuf.insts()->emit_int16(d16);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D32()
|
// EMIT_D32()
|
||||||
void emit_d32(CodeBuffer &cbuf, int d32) {
|
void emit_d32(CodeBuffer &cbuf, int d32) {
|
||||||
*((int *)(cbuf.code_end())) = d32;
|
cbuf.insts()->emit_int32(d32);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit 32 bit value and construct relocation entry from relocInfo::relocType
|
// emit 32 bit value and construct relocation entry from relocInfo::relocType
|
||||||
void emit_d32_reloc(CodeBuffer &cbuf, int d32, relocInfo::relocType reloc,
|
void emit_d32_reloc(CodeBuffer &cbuf, int d32, relocInfo::relocType reloc,
|
||||||
int format) {
|
int format) {
|
||||||
cbuf.relocate(cbuf.inst_mark(), reloc, format);
|
cbuf.relocate(cbuf.insts_mark(), reloc, format);
|
||||||
|
cbuf.insts()->emit_int32(d32);
|
||||||
*((int *)(cbuf.code_end())) = d32;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit 32 bit value and construct relocation entry from RelocationHolder
|
// emit 32 bit value and construct relocation entry from RelocationHolder
|
||||||
@ -408,10 +400,8 @@ void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec,
|
|||||||
assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cbuf.relocate(cbuf.inst_mark(), rspec, format);
|
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||||
|
cbuf.insts()->emit_int32(d32);
|
||||||
*((int *)(cbuf.code_end())) = d32;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access stack slot for load or store
|
// Access stack slot for load or store
|
||||||
@ -613,7 +603,7 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|||||||
emit_rm(cbuf, 0x3, 0x05, ESP_enc);
|
emit_rm(cbuf, 0x3, 0x05, ESP_enc);
|
||||||
emit_d32(cbuf, framesize);
|
emit_d32(cbuf, framesize);
|
||||||
}
|
}
|
||||||
C->set_frame_complete(cbuf.code_end() - cbuf.code_begin());
|
C->set_frame_complete(cbuf.insts_size());
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (VerifyStackAtCalls) {
|
if (VerifyStackAtCalls) {
|
||||||
@ -695,7 +685,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|||||||
emit_opcode(cbuf, 0x58 | EBP_enc);
|
emit_opcode(cbuf, 0x58 | EBP_enc);
|
||||||
|
|
||||||
if( do_polling() && C->is_method_compilation() ) {
|
if( do_polling() && C->is_method_compilation() ) {
|
||||||
cbuf.relocate(cbuf.code_end(), relocInfo::poll_return_type, 0);
|
cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
|
||||||
emit_opcode(cbuf,0x85);
|
emit_opcode(cbuf,0x85);
|
||||||
emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
|
emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
|
||||||
emit_d32(cbuf, (intptr_t)os::get_polling_page());
|
emit_d32(cbuf, (intptr_t)os::get_polling_page());
|
||||||
@ -1211,9 +1201,9 @@ void emit_java_to_interp(CodeBuffer &cbuf ) {
|
|||||||
// mov rbx,0
|
// mov rbx,0
|
||||||
// jmp -1
|
// jmp -1
|
||||||
|
|
||||||
address mark = cbuf.inst_mark(); // get mark within main instrs section
|
address mark = cbuf.insts_mark(); // get mark within main instrs section
|
||||||
|
|
||||||
// Note that the code buffer's inst_mark is always relative to insts.
|
// Note that the code buffer's insts_mark is always relative to insts.
|
||||||
// That's why we must use the macroassembler to generate a stub.
|
// That's why we must use the macroassembler to generate a stub.
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
|
|
||||||
@ -1228,7 +1218,7 @@ void emit_java_to_interp(CodeBuffer &cbuf ) {
|
|||||||
__ jump(RuntimeAddress(__ pc()));
|
__ jump(RuntimeAddress(__ pc()));
|
||||||
|
|
||||||
__ end_a_stub();
|
__ end_a_stub();
|
||||||
// Update current stubs pointer and restore code_end.
|
// Update current stubs pointer and restore insts_end.
|
||||||
}
|
}
|
||||||
// size of call stub, compiled java to interpretor
|
// size of call stub, compiled java to interpretor
|
||||||
uint size_java_to_interp() {
|
uint size_java_to_interp() {
|
||||||
@ -1254,7 +1244,7 @@ void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
|
|||||||
void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
MacroAssembler masm(&cbuf);
|
MacroAssembler masm(&cbuf);
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
uint code_size = cbuf.code_size();
|
uint insts_size = cbuf.insts_size();
|
||||||
#endif
|
#endif
|
||||||
masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
|
masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
|
||||||
masm.jump_cc(Assembler::notEqual,
|
masm.jump_cc(Assembler::notEqual,
|
||||||
@ -1266,7 +1256,7 @@ void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|||||||
nops_cnt += 1;
|
nops_cnt += 1;
|
||||||
masm.nop(nops_cnt);
|
masm.nop(nops_cnt);
|
||||||
|
|
||||||
assert(cbuf.code_size() - code_size == size(ra_), "checking code size of inline cache node");
|
assert(cbuf.insts_size() - insts_size == size(ra_), "checking code size of inline cache node");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
|
uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
|
||||||
@ -1288,14 +1278,14 @@ uint size_exception_handler() {
|
|||||||
// and call a VM stub routine.
|
// and call a VM stub routine.
|
||||||
int emit_exception_handler(CodeBuffer& cbuf) {
|
int emit_exception_handler(CodeBuffer& cbuf) {
|
||||||
|
|
||||||
// Note that the code buffer's inst_mark is always relative to insts.
|
// Note that the code buffer's insts_mark is always relative to insts.
|
||||||
// That's why we must use the macroassembler to generate a handler.
|
// That's why we must use the macroassembler to generate a handler.
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
address base =
|
address base =
|
||||||
__ start_a_stub(size_exception_handler());
|
__ start_a_stub(size_exception_handler());
|
||||||
if (base == NULL) return 0; // CodeBuffer::expand failed
|
if (base == NULL) return 0; // CodeBuffer::expand failed
|
||||||
int offset = __ offset();
|
int offset = __ offset();
|
||||||
__ jump(RuntimeAddress(OptoRuntime::exception_blob()->instructions_begin()));
|
__ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
|
||||||
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
|
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
|
||||||
__ end_a_stub();
|
__ end_a_stub();
|
||||||
return offset;
|
return offset;
|
||||||
@ -1313,7 +1303,7 @@ uint size_deopt_handler() {
|
|||||||
// Emit deopt handler code.
|
// Emit deopt handler code.
|
||||||
int emit_deopt_handler(CodeBuffer& cbuf) {
|
int emit_deopt_handler(CodeBuffer& cbuf) {
|
||||||
|
|
||||||
// Note that the code buffer's inst_mark is always relative to insts.
|
// Note that the code buffer's insts_mark is always relative to insts.
|
||||||
// That's why we must use the macroassembler to generate a handler.
|
// That's why we must use the macroassembler to generate a handler.
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
address base =
|
address base =
|
||||||
@ -1728,12 +1718,12 @@ encode %{
|
|||||||
|
|
||||||
enc_class Lbl (label labl) %{ // JMP, CALL
|
enc_class Lbl (label labl) %{ // JMP, CALL
|
||||||
Label *l = $labl$$label;
|
Label *l = $labl$$label;
|
||||||
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size()+4)) : 0);
|
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class LblShort (label labl) %{ // JMP, CALL
|
enc_class LblShort (label labl) %{ // JMP, CALL
|
||||||
Label *l = $labl$$label;
|
Label *l = $labl$$label;
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size()+1)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
|
||||||
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
emit_d8(cbuf, disp);
|
emit_d8(cbuf, disp);
|
||||||
%}
|
%}
|
||||||
@ -1764,13 +1754,13 @@ encode %{
|
|||||||
Label *l = $labl$$label;
|
Label *l = $labl$$label;
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
||||||
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size()+4)) : 0);
|
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class JccShort (cmpOp cop, label labl) %{ // JCC
|
enc_class JccShort (cmpOp cop, label labl) %{ // JCC
|
||||||
Label *l = $labl$$label;
|
Label *l = $labl$$label;
|
||||||
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size()+1)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
|
||||||
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
emit_d8(cbuf, disp);
|
emit_d8(cbuf, disp);
|
||||||
%}
|
%}
|
||||||
@ -1838,10 +1828,10 @@ encode %{
|
|||||||
|
|
||||||
enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
|
enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
|
||||||
// This is the instruction starting address for relocation info.
|
// This is the instruction starting address for relocation info.
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
|
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
|
||||||
runtime_call_Relocation::spec(), RELOC_IMM32 );
|
runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
|
|
||||||
if (UseSSE >= 2) {
|
if (UseSSE >= 2) {
|
||||||
@ -1871,12 +1861,12 @@ encode %{
|
|||||||
|
|
||||||
enc_class pre_call_FPU %{
|
enc_class pre_call_FPU %{
|
||||||
// If method sets FPU control word restore it here
|
// If method sets FPU control word restore it here
|
||||||
debug_only(int off0 = cbuf.code_size());
|
debug_only(int off0 = cbuf.insts_size());
|
||||||
if( Compile::current()->in_24_bit_fp_mode() ) {
|
if( Compile::current()->in_24_bit_fp_mode() ) {
|
||||||
MacroAssembler masm(&cbuf);
|
MacroAssembler masm(&cbuf);
|
||||||
masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
|
masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
|
||||||
}
|
}
|
||||||
debug_only(int off1 = cbuf.code_size());
|
debug_only(int off1 = cbuf.insts_size());
|
||||||
assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction");
|
assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction");
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -1889,12 +1879,12 @@ encode %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class preserve_SP %{
|
enc_class preserve_SP %{
|
||||||
debug_only(int off0 = cbuf.code_size());
|
debug_only(int off0 = cbuf.insts_size());
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
// RBP is preserved across all calls, even compiled calls.
|
// RBP is preserved across all calls, even compiled calls.
|
||||||
// Use it to preserve RSP in places where the callee might change the SP.
|
// Use it to preserve RSP in places where the callee might change the SP.
|
||||||
__ movptr(rbp_mh_SP_save, rsp);
|
__ movptr(rbp_mh_SP_save, rsp);
|
||||||
debug_only(int off1 = cbuf.code_size());
|
debug_only(int off1 = cbuf.insts_size());
|
||||||
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -1906,16 +1896,16 @@ encode %{
|
|||||||
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
|
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
|
||||||
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
||||||
// who we intended to call.
|
// who we intended to call.
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
if ( !_method ) {
|
if ( !_method ) {
|
||||||
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
|
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
|
||||||
runtime_call_Relocation::spec(), RELOC_IMM32 );
|
runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
} else if(_optimized_virtual) {
|
} else if(_optimized_virtual) {
|
||||||
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
|
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
|
||||||
opt_virtual_call_Relocation::spec(), RELOC_IMM32 );
|
opt_virtual_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
} else {
|
} else {
|
||||||
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
|
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
|
||||||
static_call_Relocation::spec(), RELOC_IMM32 );
|
static_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
}
|
}
|
||||||
if( _method ) { // Emit stub for static call
|
if( _method ) { // Emit stub for static call
|
||||||
@ -1927,15 +1917,15 @@ encode %{
|
|||||||
// !!!!!
|
// !!!!!
|
||||||
// Generate "Mov EAX,0x00", placeholder instruction to load oop-info
|
// Generate "Mov EAX,0x00", placeholder instruction to load oop-info
|
||||||
// emit_call_dynamic_prologue( cbuf );
|
// emit_call_dynamic_prologue( cbuf );
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xB8 + EAX_enc); // mov EAX,-1
|
emit_opcode(cbuf, 0xB8 + EAX_enc); // mov EAX,-1
|
||||||
emit_d32_reloc(cbuf, (int)Universe::non_oop_word(), oop_Relocation::spec_for_immediate(), RELOC_IMM32);
|
emit_d32_reloc(cbuf, (int)Universe::non_oop_word(), oop_Relocation::spec_for_immediate(), RELOC_IMM32);
|
||||||
address virtual_call_oop_addr = cbuf.inst_mark();
|
address virtual_call_oop_addr = cbuf.insts_mark();
|
||||||
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
||||||
// who we intended to call.
|
// who we intended to call.
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
|
emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
|
||||||
virtual_call_Relocation::spec(virtual_call_oop_addr), RELOC_IMM32 );
|
virtual_call_Relocation::spec(virtual_call_oop_addr), RELOC_IMM32 );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -1944,7 +1934,7 @@ encode %{
|
|||||||
assert( -128 <= disp && disp <= 127, "compiled_code_offset isn't small");
|
assert( -128 <= disp && disp <= 127, "compiled_code_offset isn't small");
|
||||||
|
|
||||||
// CALL *[EAX+in_bytes(methodOopDesc::from_compiled_code_entry_point_offset())]
|
// CALL *[EAX+in_bytes(methodOopDesc::from_compiled_code_entry_point_offset())]
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_rm(cbuf, 0x01, $secondary, EAX_enc ); // R/M byte
|
emit_rm(cbuf, 0x01, $secondary, EAX_enc ); // R/M byte
|
||||||
emit_d8(cbuf, disp); // Displacement
|
emit_d8(cbuf, disp); // Displacement
|
||||||
@ -1976,9 +1966,9 @@ encode %{
|
|||||||
// emit_rm(cbuf, 0x3, EBP_enc, EBP_enc);
|
// emit_rm(cbuf, 0x3, EBP_enc, EBP_enc);
|
||||||
//
|
//
|
||||||
// // CALL to interpreter.
|
// // CALL to interpreter.
|
||||||
// cbuf.set_inst_mark();
|
// cbuf.set_insts_mark();
|
||||||
// $$$emit8$primary;
|
// $$$emit8$primary;
|
||||||
// emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.code_end()) - 4),
|
// emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.insts_end()) - 4),
|
||||||
// runtime_call_Relocation::spec(), RELOC_IMM32 );
|
// runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// %}
|
// %}
|
||||||
|
|
||||||
@ -2087,7 +2077,7 @@ encode %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class Opc_MemImm_F(immF src) %{
|
enc_class Opc_MemImm_F(immF src) %{
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_rm(cbuf, 0x0, $secondary, 0x5);
|
emit_rm(cbuf, 0x0, $secondary, 0x5);
|
||||||
emit_float_constant(cbuf, $src$$constant);
|
emit_float_constant(cbuf, $src$$constant);
|
||||||
@ -2280,7 +2270,7 @@ encode %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class set_instruction_start( ) %{
|
enc_class set_instruction_start( ) %{
|
||||||
cbuf.set_inst_mark(); // Mark start of opcode for reloc info in mem operand
|
cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class RegMem (eRegI ereg, memory mem) %{ // emit_reg_mem
|
enc_class RegMem (eRegI ereg, memory mem) %{ // emit_reg_mem
|
||||||
@ -2429,7 +2419,7 @@ encode %{
|
|||||||
emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it)
|
emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it)
|
||||||
emit_d8( cbuf, 0xC0-1+$src$$reg );
|
emit_d8( cbuf, 0xC0-1+$src$$reg );
|
||||||
}
|
}
|
||||||
cbuf.set_inst_mark(); // Mark start of opcode for reloc info in mem operand
|
cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
|
||||||
emit_opcode(cbuf,$primary);
|
emit_opcode(cbuf,$primary);
|
||||||
encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
|
encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
|
||||||
%}
|
%}
|
||||||
@ -2474,7 +2464,7 @@ encode %{
|
|||||||
emit_opcode(cbuf,0x1B);
|
emit_opcode(cbuf,0x1B);
|
||||||
emit_rm(cbuf, 0x3, tmpReg, tmpReg);
|
emit_rm(cbuf, 0x3, tmpReg, tmpReg);
|
||||||
// AND $tmp,$y
|
// AND $tmp,$y
|
||||||
cbuf.set_inst_mark(); // Mark start of opcode for reloc info in mem operand
|
cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
|
||||||
emit_opcode(cbuf,0x23);
|
emit_opcode(cbuf,0x23);
|
||||||
int reg_encoding = tmpReg;
|
int reg_encoding = tmpReg;
|
||||||
int base = $mem$$base;
|
int base = $mem$$base;
|
||||||
@ -3157,9 +3147,9 @@ encode %{
|
|||||||
// PUSH src2.lo
|
// PUSH src2.lo
|
||||||
emit_opcode(cbuf, 0x50+$src2$$reg );
|
emit_opcode(cbuf, 0x50+$src2$$reg );
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::ldiv) - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::ldiv) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// Restore stack
|
// Restore stack
|
||||||
emit_opcode(cbuf, 0x83); // add SP, #framesize
|
emit_opcode(cbuf, 0x83); // add SP, #framesize
|
||||||
emit_rm(cbuf, 0x3, 0x00, ESP_enc);
|
emit_rm(cbuf, 0x3, 0x00, ESP_enc);
|
||||||
@ -3176,9 +3166,9 @@ encode %{
|
|||||||
// PUSH src2.lo
|
// PUSH src2.lo
|
||||||
emit_opcode(cbuf, 0x50+$src2$$reg );
|
emit_opcode(cbuf, 0x50+$src2$$reg );
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// Restore stack
|
// Restore stack
|
||||||
emit_opcode(cbuf, 0x83); // add SP, #framesize
|
emit_opcode(cbuf, 0x83); // add SP, #framesize
|
||||||
emit_rm(cbuf, 0x3, 0x00, ESP_enc);
|
emit_rm(cbuf, 0x3, 0x00, ESP_enc);
|
||||||
@ -3824,9 +3814,9 @@ encode %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_rethrow() %{
|
enc_class enc_rethrow() %{
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xE9); // jmp entry
|
emit_opcode(cbuf, 0xE9); // jmp entry
|
||||||
emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.code_end())-4,
|
emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.insts_end())-4,
|
||||||
runtime_call_Relocation::spec(), RELOC_IMM32 );
|
runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -3873,9 +3863,9 @@ encode %{
|
|||||||
emit_opcode(cbuf,0xD9 ); // FLD ST(i)
|
emit_opcode(cbuf,0xD9 ); // FLD ST(i)
|
||||||
emit_d8 (cbuf,0xC0-1+$src$$reg );
|
emit_d8 (cbuf,0xC0-1+$src$$reg );
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// Carry on here...
|
// Carry on here...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -3915,9 +3905,9 @@ encode %{
|
|||||||
emit_opcode(cbuf,0xD9 ); // FLD ST(i)
|
emit_opcode(cbuf,0xD9 ); // FLD ST(i)
|
||||||
emit_d8 (cbuf,0xC0-1+$src$$reg );
|
emit_d8 (cbuf,0xC0-1+$src$$reg );
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// Carry on here...
|
// Carry on here...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -3988,9 +3978,9 @@ encode %{
|
|||||||
emit_d8(cbuf,0x04);
|
emit_d8(cbuf,0x04);
|
||||||
|
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// Carry on here...
|
// Carry on here...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4062,9 +4052,9 @@ encode %{
|
|||||||
emit_d8(cbuf,0x08);
|
emit_d8(cbuf,0x08);
|
||||||
|
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
// Carry on here...
|
// Carry on here...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4122,9 +4112,9 @@ encode %{
|
|||||||
emit_d8(cbuf, $primary ? 0x8 : 0x4);
|
emit_d8(cbuf, $primary ? 0x8 : 0x4);
|
||||||
|
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf,0xE8); // Call into runtime
|
emit_opcode(cbuf,0xE8); // Call into runtime
|
||||||
emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.code_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
|
||||||
|
|
||||||
// Carry on here...
|
// Carry on here...
|
||||||
%}
|
%}
|
||||||
@ -4321,7 +4311,7 @@ encode %{
|
|||||||
// so the memory operand is used twice in the encoding.
|
// so the memory operand is used twice in the encoding.
|
||||||
enc_class enc_storeL_volatile( memory mem, stackSlotL src ) %{
|
enc_class enc_storeL_volatile( memory mem, stackSlotL src ) %{
|
||||||
store_to_stackslot( cbuf, 0x0DF, 0x05, $src$$disp );
|
store_to_stackslot( cbuf, 0x0DF, 0x05, $src$$disp );
|
||||||
cbuf.set_inst_mark(); // Mark start of FIST in case $mem has an oop
|
cbuf.set_insts_mark(); // Mark start of FIST in case $mem has an oop
|
||||||
emit_opcode(cbuf,0xDF);
|
emit_opcode(cbuf,0xDF);
|
||||||
int rm_byte_opcode = 0x07;
|
int rm_byte_opcode = 0x07;
|
||||||
int base = $mem$$base;
|
int base = $mem$$base;
|
||||||
@ -4345,7 +4335,7 @@ encode %{
|
|||||||
bool disp_is_oop = $src->disp_is_oop(); // disp-as-oop when working with static globals
|
bool disp_is_oop = $src->disp_is_oop(); // disp-as-oop when working with static globals
|
||||||
encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
|
encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
|
||||||
}
|
}
|
||||||
cbuf.set_inst_mark(); // Mark start of MOVSD in case $mem has an oop
|
cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop
|
||||||
{ // MOVSD $mem,$tmp ! atomic long store
|
{ // MOVSD $mem,$tmp ! atomic long store
|
||||||
emit_opcode(cbuf,0xF2);
|
emit_opcode(cbuf,0xF2);
|
||||||
emit_opcode(cbuf,0x0F);
|
emit_opcode(cbuf,0x0F);
|
||||||
@ -4378,7 +4368,7 @@ encode %{
|
|||||||
emit_opcode(cbuf,0x62);
|
emit_opcode(cbuf,0x62);
|
||||||
emit_rm(cbuf, 0x3, $tmp$$reg, $tmp2$$reg);
|
emit_rm(cbuf, 0x3, $tmp$$reg, $tmp2$$reg);
|
||||||
}
|
}
|
||||||
cbuf.set_inst_mark(); // Mark start of MOVSD in case $mem has an oop
|
cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop
|
||||||
{ // MOVSD $mem,$tmp ! atomic long store
|
{ // MOVSD $mem,$tmp ! atomic long store
|
||||||
emit_opcode(cbuf,0xF2);
|
emit_opcode(cbuf,0xF2);
|
||||||
emit_opcode(cbuf,0x0F);
|
emit_opcode(cbuf,0x0F);
|
||||||
@ -4399,7 +4389,7 @@ encode %{
|
|||||||
// A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0
|
// A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0
|
||||||
|
|
||||||
enc_class Safepoint_Poll() %{
|
enc_class Safepoint_Poll() %{
|
||||||
cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_type, 0);
|
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0);
|
||||||
emit_opcode(cbuf,0x85);
|
emit_opcode(cbuf,0x85);
|
||||||
emit_rm (cbuf, 0x0, 0x7, 0x5);
|
emit_rm (cbuf, 0x0, 0x7, 0x5);
|
||||||
emit_d32(cbuf, (intptr_t)os::get_polling_page());
|
emit_d32(cbuf, (intptr_t)os::get_polling_page());
|
||||||
@ -12932,7 +12922,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
|
|||||||
bool ok = false;
|
bool ok = false;
|
||||||
if ($cop$$cmpcode == Assembler::notEqual) {
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
// the two jumps 6 bytes apart so the jump distances are too
|
// the two jumps 6 bytes apart so the jump distances are too
|
||||||
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
|
||||||
} else if ($cop$$cmpcode == Assembler::equal) {
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
parity_disp = 6;
|
parity_disp = 6;
|
||||||
ok = true;
|
ok = true;
|
||||||
@ -12942,7 +12932,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
|
|||||||
emit_d32(cbuf, parity_disp);
|
emit_d32(cbuf, parity_disp);
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
|
||||||
emit_d32(cbuf, disp);
|
emit_d32(cbuf, disp);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_jcc);
|
ins_pipe(pipe_jcc);
|
||||||
@ -13128,7 +13118,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
|
|||||||
emit_cc(cbuf, $primary, Assembler::parity);
|
emit_cc(cbuf, $primary, Assembler::parity);
|
||||||
int parity_disp = -1;
|
int parity_disp = -1;
|
||||||
if ($cop$$cmpcode == Assembler::notEqual) {
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
|
||||||
} else if ($cop$$cmpcode == Assembler::equal) {
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
parity_disp = 2;
|
parity_disp = 2;
|
||||||
} else {
|
} else {
|
||||||
@ -13136,7 +13126,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
|
|||||||
}
|
}
|
||||||
emit_d8(cbuf, parity_disp);
|
emit_d8(cbuf, parity_disp);
|
||||||
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
|
||||||
emit_d8(cbuf, disp);
|
emit_d8(cbuf, disp);
|
||||||
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
|
||||||
|
@ -619,62 +619,48 @@ void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// EMIT_RM()
|
// EMIT_RM()
|
||||||
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3)
|
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
||||||
{
|
|
||||||
unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
|
unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
|
||||||
*(cbuf.code_end()) = c;
|
cbuf.insts()->emit_int8(c);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_CC()
|
// EMIT_CC()
|
||||||
void emit_cc(CodeBuffer &cbuf, int f1, int f2)
|
void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
|
||||||
{
|
|
||||||
unsigned char c = (unsigned char) (f1 | f2);
|
unsigned char c = (unsigned char) (f1 | f2);
|
||||||
*(cbuf.code_end()) = c;
|
cbuf.insts()->emit_int8(c);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_OPCODE()
|
// EMIT_OPCODE()
|
||||||
void emit_opcode(CodeBuffer &cbuf, int code)
|
void emit_opcode(CodeBuffer &cbuf, int code) {
|
||||||
{
|
cbuf.insts()->emit_int8((unsigned char) code);
|
||||||
*(cbuf.code_end()) = (unsigned char) code;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_OPCODE() w/ relocation information
|
// EMIT_OPCODE() w/ relocation information
|
||||||
void emit_opcode(CodeBuffer &cbuf,
|
void emit_opcode(CodeBuffer &cbuf,
|
||||||
int code, relocInfo::relocType reloc, int offset, int format)
|
int code, relocInfo::relocType reloc, int offset, int format)
|
||||||
{
|
{
|
||||||
cbuf.relocate(cbuf.inst_mark() + offset, reloc, format);
|
cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
|
||||||
emit_opcode(cbuf, code);
|
emit_opcode(cbuf, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D8()
|
// EMIT_D8()
|
||||||
void emit_d8(CodeBuffer &cbuf, int d8)
|
void emit_d8(CodeBuffer &cbuf, int d8) {
|
||||||
{
|
cbuf.insts()->emit_int8((unsigned char) d8);
|
||||||
*(cbuf.code_end()) = (unsigned char) d8;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D16()
|
// EMIT_D16()
|
||||||
void emit_d16(CodeBuffer &cbuf, int d16)
|
void emit_d16(CodeBuffer &cbuf, int d16) {
|
||||||
{
|
cbuf.insts()->emit_int16(d16);
|
||||||
*((short *)(cbuf.code_end())) = d16;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D32()
|
// EMIT_D32()
|
||||||
void emit_d32(CodeBuffer &cbuf, int d32)
|
void emit_d32(CodeBuffer &cbuf, int d32) {
|
||||||
{
|
cbuf.insts()->emit_int32(d32);
|
||||||
*((int *)(cbuf.code_end())) = d32;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_D64()
|
// EMIT_D64()
|
||||||
void emit_d64(CodeBuffer &cbuf, int64_t d64)
|
void emit_d64(CodeBuffer &cbuf, int64_t d64) {
|
||||||
{
|
cbuf.insts()->emit_int64(d64);
|
||||||
*((int64_t*) (cbuf.code_end())) = d64;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit 32 bit value and construct relocation entry from relocInfo::relocType
|
// emit 32 bit value and construct relocation entry from relocInfo::relocType
|
||||||
@ -684,32 +670,24 @@ void emit_d32_reloc(CodeBuffer& cbuf,
|
|||||||
int format)
|
int format)
|
||||||
{
|
{
|
||||||
assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
|
assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
|
||||||
cbuf.relocate(cbuf.inst_mark(), reloc, format);
|
cbuf.relocate(cbuf.insts_mark(), reloc, format);
|
||||||
|
cbuf.insts()->emit_int32(d32);
|
||||||
*((int*) (cbuf.code_end())) = d32;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit 32 bit value and construct relocation entry from RelocationHolder
|
// emit 32 bit value and construct relocation entry from RelocationHolder
|
||||||
void emit_d32_reloc(CodeBuffer& cbuf,
|
void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
|
||||||
int d32,
|
|
||||||
RelocationHolder const& rspec,
|
|
||||||
int format)
|
|
||||||
{
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
||||||
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
|
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
|
||||||
assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cbuf.relocate(cbuf.inst_mark(), rspec, format);
|
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||||
|
cbuf.insts()->emit_int32(d32);
|
||||||
*((int* )(cbuf.code_end())) = d32;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
|
void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
|
||||||
address next_ip = cbuf.code_end() + 4;
|
address next_ip = cbuf.insts_end() + 4;
|
||||||
emit_d32_reloc(cbuf, (int) (addr - next_ip),
|
emit_d32_reloc(cbuf, (int) (addr - next_ip),
|
||||||
external_word_Relocation::spec(addr),
|
external_word_Relocation::spec(addr),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
@ -717,23 +695,13 @@ void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
|
|||||||
|
|
||||||
|
|
||||||
// emit 64 bit value and construct relocation entry from relocInfo::relocType
|
// emit 64 bit value and construct relocation entry from relocInfo::relocType
|
||||||
void emit_d64_reloc(CodeBuffer& cbuf,
|
void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
|
||||||
int64_t d64,
|
cbuf.relocate(cbuf.insts_mark(), reloc, format);
|
||||||
relocInfo::relocType reloc,
|
cbuf.insts()->emit_int64(d64);
|
||||||
int format)
|
|
||||||
{
|
|
||||||
cbuf.relocate(cbuf.inst_mark(), reloc, format);
|
|
||||||
|
|
||||||
*((int64_t*) (cbuf.code_end())) = d64;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit 64 bit value and construct relocation entry from RelocationHolder
|
// emit 64 bit value and construct relocation entry from RelocationHolder
|
||||||
void emit_d64_reloc(CodeBuffer& cbuf,
|
void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
|
||||||
int64_t d64,
|
|
||||||
RelocationHolder const& rspec,
|
|
||||||
int format)
|
|
||||||
{
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
||||||
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
|
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
|
||||||
@ -741,10 +709,8 @@ void emit_d64_reloc(CodeBuffer& cbuf,
|
|||||||
"cannot embed scavengable oops in code");
|
"cannot embed scavengable oops in code");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cbuf.relocate(cbuf.inst_mark(), rspec, format);
|
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||||
|
cbuf.insts()->emit_int64(d64);
|
||||||
*((int64_t*) (cbuf.code_end())) = d64;
|
|
||||||
cbuf.set_code_end(cbuf.code_end() + 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access stack slot for load or store
|
// Access stack slot for load or store
|
||||||
@ -966,7 +932,7 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
C->set_frame_complete(cbuf.code_end() - cbuf.code_begin());
|
C->set_frame_complete(cbuf.insts_size());
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (VerifyStackAtCalls) {
|
if (VerifyStackAtCalls) {
|
||||||
@ -1050,11 +1016,11 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
|||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
||||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_return_type, 0); // XXX
|
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX
|
||||||
emit_opcode(cbuf, 0x85); // testl
|
emit_opcode(cbuf, 0x85); // testl
|
||||||
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
||||||
// cbuf.inst_mark() is beginning of instruction
|
// cbuf.insts_mark() is beginning of instruction
|
||||||
emit_d32_reloc(cbuf, os::get_polling_page());
|
emit_d32_reloc(cbuf, os::get_polling_page());
|
||||||
// relocInfo::poll_return_type,
|
// relocInfo::poll_return_type,
|
||||||
}
|
}
|
||||||
@ -1814,9 +1780,9 @@ void emit_java_to_interp(CodeBuffer& cbuf)
|
|||||||
// movq rbx, 0
|
// movq rbx, 0
|
||||||
// jmp -5 # to self
|
// jmp -5 # to self
|
||||||
|
|
||||||
address mark = cbuf.inst_mark(); // get mark within main instrs section
|
address mark = cbuf.insts_mark(); // get mark within main instrs section
|
||||||
|
|
||||||
// Note that the code buffer's inst_mark is always relative to insts.
|
// Note that the code buffer's insts_mark is always relative to insts.
|
||||||
// That's why we must use the macroassembler to generate a stub.
|
// That's why we must use the macroassembler to generate a stub.
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
|
|
||||||
@ -1830,7 +1796,7 @@ void emit_java_to_interp(CodeBuffer& cbuf)
|
|||||||
// This is recognized as unresolved by relocs/nativeinst/ic code
|
// This is recognized as unresolved by relocs/nativeinst/ic code
|
||||||
__ jump(RuntimeAddress(__ pc()));
|
__ jump(RuntimeAddress(__ pc()));
|
||||||
|
|
||||||
// Update current stubs pointer and restore code_end.
|
// Update current stubs pointer and restore insts_end.
|
||||||
__ end_a_stub();
|
__ end_a_stub();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1868,7 +1834,7 @@ void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
|||||||
void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
||||||
{
|
{
|
||||||
MacroAssembler masm(&cbuf);
|
MacroAssembler masm(&cbuf);
|
||||||
uint code_size = cbuf.code_size();
|
uint insts_size = cbuf.insts_size();
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
masm.load_klass(rscratch1, j_rarg0);
|
masm.load_klass(rscratch1, j_rarg0);
|
||||||
masm.cmpptr(rax, rscratch1);
|
masm.cmpptr(rax, rscratch1);
|
||||||
@ -1880,7 +1846,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
|||||||
|
|
||||||
/* WARNING these NOPs are critical so that verified entry point is properly
|
/* WARNING these NOPs are critical so that verified entry point is properly
|
||||||
4 bytes aligned for patching by NativeJump::patch_verified_entry() */
|
4 bytes aligned for patching by NativeJump::patch_verified_entry() */
|
||||||
int nops_cnt = 4 - ((cbuf.code_size() - code_size) & 0x3);
|
int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
|
||||||
if (OptoBreakpoint) {
|
if (OptoBreakpoint) {
|
||||||
// Leave space for int3
|
// Leave space for int3
|
||||||
nops_cnt -= 1;
|
nops_cnt -= 1;
|
||||||
@ -1910,14 +1876,14 @@ uint size_exception_handler()
|
|||||||
int emit_exception_handler(CodeBuffer& cbuf)
|
int emit_exception_handler(CodeBuffer& cbuf)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Note that the code buffer's inst_mark is always relative to insts.
|
// Note that the code buffer's insts_mark is always relative to insts.
|
||||||
// That's why we must use the macroassembler to generate a handler.
|
// That's why we must use the macroassembler to generate a handler.
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
address base =
|
address base =
|
||||||
__ start_a_stub(size_exception_handler());
|
__ start_a_stub(size_exception_handler());
|
||||||
if (base == NULL) return 0; // CodeBuffer::expand failed
|
if (base == NULL) return 0; // CodeBuffer::expand failed
|
||||||
int offset = __ offset();
|
int offset = __ offset();
|
||||||
__ jump(RuntimeAddress(OptoRuntime::exception_blob()->instructions_begin()));
|
__ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
|
||||||
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
|
assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
|
||||||
__ end_a_stub();
|
__ end_a_stub();
|
||||||
return offset;
|
return offset;
|
||||||
@ -1933,7 +1899,7 @@ uint size_deopt_handler()
|
|||||||
int emit_deopt_handler(CodeBuffer& cbuf)
|
int emit_deopt_handler(CodeBuffer& cbuf)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Note that the code buffer's inst_mark is always relative to insts.
|
// Note that the code buffer's insts_mark is always relative to insts.
|
||||||
// That's why we must use the macroassembler to generate a handler.
|
// That's why we must use the macroassembler to generate a handler.
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
address base =
|
address base =
|
||||||
@ -1962,7 +1928,7 @@ static void emit_double_constant(CodeBuffer& cbuf, double x) {
|
|||||||
address double_address = __ double_constant(x);
|
address double_address = __ double_constant(x);
|
||||||
cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
|
cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) (double_address - cbuf.code_end() - 4),
|
(int) (double_address - cbuf.insts_end() - 4),
|
||||||
internal_word_Relocation::spec(double_address),
|
internal_word_Relocation::spec(double_address),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
}
|
}
|
||||||
@ -1973,7 +1939,7 @@ static void emit_float_constant(CodeBuffer& cbuf, float x) {
|
|||||||
address float_address = __ float_constant(x);
|
address float_address = __ float_constant(x);
|
||||||
cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
|
cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) (float_address - cbuf.code_end() - 4),
|
(int) (float_address - cbuf.insts_end() - 4),
|
||||||
internal_word_Relocation::spec(float_address),
|
internal_word_Relocation::spec(float_address),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
}
|
}
|
||||||
@ -2481,14 +2447,14 @@ encode %{
|
|||||||
%{
|
%{
|
||||||
// JMP, CALL
|
// JMP, CALL
|
||||||
Label* l = $labl$$label;
|
Label* l = $labl$$label;
|
||||||
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0);
|
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class LblShort(label labl)
|
enc_class LblShort(label labl)
|
||||||
%{
|
%{
|
||||||
// JMP, CALL
|
// JMP, CALL
|
||||||
Label* l = $labl$$label;
|
Label* l = $labl$$label;
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
|
||||||
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
emit_d8(cbuf, disp);
|
emit_d8(cbuf, disp);
|
||||||
%}
|
%}
|
||||||
@ -2517,7 +2483,7 @@ encode %{
|
|||||||
Label* l = $labl$$label;
|
Label* l = $labl$$label;
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
||||||
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0);
|
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class JccShort (cmpOp cop, label labl)
|
enc_class JccShort (cmpOp cop, label labl)
|
||||||
@ -2525,7 +2491,7 @@ encode %{
|
|||||||
// JCC
|
// JCC
|
||||||
Label *l = $labl$$label;
|
Label *l = $labl$$label;
|
||||||
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
|
||||||
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
emit_d8(cbuf, disp);
|
emit_d8(cbuf, disp);
|
||||||
%}
|
%}
|
||||||
@ -2609,22 +2575,22 @@ encode %{
|
|||||||
%{
|
%{
|
||||||
// CALL Java_To_Interpreter
|
// CALL Java_To_Interpreter
|
||||||
// This is the instruction starting address for relocation info.
|
// This is the instruction starting address for relocation info.
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
// CALL directly to the runtime
|
// CALL directly to the runtime
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
|
(int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class preserve_SP %{
|
enc_class preserve_SP %{
|
||||||
debug_only(int off0 = cbuf.code_size());
|
debug_only(int off0 = cbuf.insts_size());
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
// RBP is preserved across all calls, even compiled calls.
|
// RBP is preserved across all calls, even compiled calls.
|
||||||
// Use it to preserve RSP in places where the callee might change the SP.
|
// Use it to preserve RSP in places where the callee might change the SP.
|
||||||
__ movptr(rbp_mh_SP_save, rsp);
|
__ movptr(rbp_mh_SP_save, rsp);
|
||||||
debug_only(int off1 = cbuf.code_size());
|
debug_only(int off1 = cbuf.insts_size());
|
||||||
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -2638,22 +2604,22 @@ encode %{
|
|||||||
// JAVA STATIC CALL
|
// JAVA STATIC CALL
|
||||||
// CALL to fixup routine. Fixup routine uses ScopeDesc info to
|
// CALL to fixup routine. Fixup routine uses ScopeDesc info to
|
||||||
// determine who we intended to call.
|
// determine who we intended to call.
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
|
|
||||||
if (!_method) {
|
if (!_method) {
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
|
(int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
} else if (_optimized_virtual) {
|
} else if (_optimized_virtual) {
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
|
(int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
|
||||||
opt_virtual_call_Relocation::spec(),
|
opt_virtual_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
} else {
|
} else {
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
|
(int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
|
||||||
static_call_Relocation::spec(),
|
static_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
}
|
}
|
||||||
@ -2669,7 +2635,7 @@ encode %{
|
|||||||
// !!!!!
|
// !!!!!
|
||||||
// Generate "movq rax, -1", placeholder instruction to load oop-info
|
// Generate "movq rax, -1", placeholder instruction to load oop-info
|
||||||
// emit_call_dynamic_prologue( cbuf );
|
// emit_call_dynamic_prologue( cbuf );
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
|
|
||||||
// movq rax, -1
|
// movq rax, -1
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
emit_opcode(cbuf, Assembler::REX_W);
|
||||||
@ -2677,13 +2643,13 @@ encode %{
|
|||||||
emit_d64_reloc(cbuf,
|
emit_d64_reloc(cbuf,
|
||||||
(int64_t) Universe::non_oop_word(),
|
(int64_t) Universe::non_oop_word(),
|
||||||
oop_Relocation::spec_for_immediate(), RELOC_IMM64);
|
oop_Relocation::spec_for_immediate(), RELOC_IMM64);
|
||||||
address virtual_call_oop_addr = cbuf.inst_mark();
|
address virtual_call_oop_addr = cbuf.insts_mark();
|
||||||
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
||||||
// who we intended to call.
|
// who we intended to call.
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4),
|
(int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
|
||||||
virtual_call_Relocation::spec(virtual_call_oop_addr),
|
virtual_call_Relocation::spec(virtual_call_oop_addr),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
%}
|
%}
|
||||||
@ -2697,7 +2663,7 @@ encode %{
|
|||||||
// assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
|
// assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
|
||||||
|
|
||||||
// callq *disp(%rax)
|
// callq *disp(%rax)
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
if (disp < 0x80) {
|
if (disp < 0x80) {
|
||||||
emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
|
emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
|
||||||
@ -3729,10 +3695,10 @@ encode %{
|
|||||||
|
|
||||||
enc_class enc_rethrow()
|
enc_class enc_rethrow()
|
||||||
%{
|
%{
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xE9); // jmp entry
|
emit_opcode(cbuf, 0xE9); // jmp entry
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int) (OptoRuntime::rethrow_stub() - cbuf.code_end() - 4),
|
(int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
%}
|
%}
|
||||||
@ -3742,7 +3708,7 @@ encode %{
|
|||||||
int dstenc = $dst$$reg;
|
int dstenc = $dst$$reg;
|
||||||
address signmask_address = (address) StubRoutines::x86::float_sign_mask();
|
address signmask_address = (address) StubRoutines::x86::float_sign_mask();
|
||||||
|
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
if (dstenc >= 8) {
|
if (dstenc >= 8) {
|
||||||
emit_opcode(cbuf, Assembler::REX_R);
|
emit_opcode(cbuf, Assembler::REX_R);
|
||||||
dstenc -= 8;
|
dstenc -= 8;
|
||||||
@ -3759,7 +3725,7 @@ encode %{
|
|||||||
int dstenc = $dst$$reg;
|
int dstenc = $dst$$reg;
|
||||||
address signmask_address = (address) StubRoutines::x86::double_sign_mask();
|
address signmask_address = (address) StubRoutines::x86::double_sign_mask();
|
||||||
|
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0x66);
|
emit_opcode(cbuf, 0x66);
|
||||||
if (dstenc >= 8) {
|
if (dstenc >= 8) {
|
||||||
emit_opcode(cbuf, Assembler::REX_R);
|
emit_opcode(cbuf, Assembler::REX_R);
|
||||||
@ -3777,7 +3743,7 @@ encode %{
|
|||||||
int dstenc = $dst$$reg;
|
int dstenc = $dst$$reg;
|
||||||
address signflip_address = (address) StubRoutines::x86::float_sign_flip();
|
address signflip_address = (address) StubRoutines::x86::float_sign_flip();
|
||||||
|
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
if (dstenc >= 8) {
|
if (dstenc >= 8) {
|
||||||
emit_opcode(cbuf, Assembler::REX_R);
|
emit_opcode(cbuf, Assembler::REX_R);
|
||||||
dstenc -= 8;
|
dstenc -= 8;
|
||||||
@ -3794,7 +3760,7 @@ encode %{
|
|||||||
int dstenc = $dst$$reg;
|
int dstenc = $dst$$reg;
|
||||||
address signflip_address = (address) StubRoutines::x86::double_sign_flip();
|
address signflip_address = (address) StubRoutines::x86::double_sign_flip();
|
||||||
|
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0x66);
|
emit_opcode(cbuf, 0x66);
|
||||||
if (dstenc >= 8) {
|
if (dstenc >= 8) {
|
||||||
emit_opcode(cbuf, Assembler::REX_R);
|
emit_opcode(cbuf, Assembler::REX_R);
|
||||||
@ -3846,11 +3812,11 @@ encode %{
|
|||||||
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
||||||
|
|
||||||
// call f2i_fixup
|
// call f2i_fixup
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xE8);
|
emit_opcode(cbuf, 0xE8);
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int)
|
(int)
|
||||||
(StubRoutines::x86::f2i_fixup() - cbuf.code_end() - 4),
|
(StubRoutines::x86::f2i_fixup() - cbuf.insts_end() - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
|
|
||||||
@ -3870,7 +3836,7 @@ encode %{
|
|||||||
address const_address = (address) StubRoutines::x86::double_sign_flip();
|
address const_address = (address) StubRoutines::x86::double_sign_flip();
|
||||||
|
|
||||||
// cmpq $dst, [0x8000000000000000]
|
// cmpq $dst, [0x8000000000000000]
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
|
emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
|
||||||
emit_opcode(cbuf, 0x39);
|
emit_opcode(cbuf, 0x39);
|
||||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||||
@ -3904,11 +3870,11 @@ encode %{
|
|||||||
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
||||||
|
|
||||||
// call f2l_fixup
|
// call f2l_fixup
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xE8);
|
emit_opcode(cbuf, 0xE8);
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int)
|
(int)
|
||||||
(StubRoutines::x86::f2l_fixup() - cbuf.code_end() - 4),
|
(StubRoutines::x86::f2l_fixup() - cbuf.insts_end() - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
|
|
||||||
@ -3960,11 +3926,11 @@ encode %{
|
|||||||
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
||||||
|
|
||||||
// call d2i_fixup
|
// call d2i_fixup
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xE8);
|
emit_opcode(cbuf, 0xE8);
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int)
|
(int)
|
||||||
(StubRoutines::x86::d2i_fixup() - cbuf.code_end() - 4),
|
(StubRoutines::x86::d2i_fixup() - cbuf.insts_end() - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
|
|
||||||
@ -3984,7 +3950,7 @@ encode %{
|
|||||||
address const_address = (address) StubRoutines::x86::double_sign_flip();
|
address const_address = (address) StubRoutines::x86::double_sign_flip();
|
||||||
|
|
||||||
// cmpq $dst, [0x8000000000000000]
|
// cmpq $dst, [0x8000000000000000]
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
|
emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR);
|
||||||
emit_opcode(cbuf, 0x39);
|
emit_opcode(cbuf, 0x39);
|
||||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||||
@ -4018,11 +3984,11 @@ encode %{
|
|||||||
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes
|
||||||
|
|
||||||
// call d2l_fixup
|
// call d2l_fixup
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
emit_opcode(cbuf, 0xE8);
|
emit_opcode(cbuf, 0xE8);
|
||||||
emit_d32_reloc(cbuf,
|
emit_d32_reloc(cbuf,
|
||||||
(int)
|
(int)
|
||||||
(StubRoutines::x86::d2l_fixup() - cbuf.code_end() - 4),
|
(StubRoutines::x86::d2l_fixup() - cbuf.insts_end() - 4),
|
||||||
runtime_call_Relocation::spec(),
|
runtime_call_Relocation::spec(),
|
||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
|
|
||||||
@ -4042,11 +4008,11 @@ encode %{
|
|||||||
%{
|
%{
|
||||||
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
||||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||||
cbuf.set_inst_mark();
|
cbuf.set_insts_mark();
|
||||||
cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_type, 0); // XXX
|
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
|
||||||
emit_opcode(cbuf, 0x85); // testl
|
emit_opcode(cbuf, 0x85); // testl
|
||||||
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
||||||
// cbuf.inst_mark() is beginning of instruction
|
// cbuf.insts_mark() is beginning of instruction
|
||||||
emit_d32_reloc(cbuf, os::get_polling_page());
|
emit_d32_reloc(cbuf, os::get_polling_page());
|
||||||
// relocInfo::poll_type,
|
// relocInfo::poll_type,
|
||||||
%}
|
%}
|
||||||
@ -12304,7 +12270,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
|||||||
int parity_disp = -1;
|
int parity_disp = -1;
|
||||||
if ($cop$$cmpcode == Assembler::notEqual) {
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
// the two jumps 6 bytes apart so the jump distances are too
|
// the two jumps 6 bytes apart so the jump distances are too
|
||||||
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
|
||||||
} else if ($cop$$cmpcode == Assembler::equal) {
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
parity_disp = 6;
|
parity_disp = 6;
|
||||||
} else {
|
} else {
|
||||||
@ -12313,7 +12279,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
|||||||
emit_d32(cbuf, parity_disp);
|
emit_d32(cbuf, parity_disp);
|
||||||
$$$emit8$primary;
|
$$$emit8$primary;
|
||||||
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
|
||||||
emit_d32(cbuf, disp);
|
emit_d32(cbuf, disp);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_jcc);
|
ins_pipe(pipe_jcc);
|
||||||
@ -12508,7 +12474,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
|||||||
emit_cc(cbuf, $primary, Assembler::parity);
|
emit_cc(cbuf, $primary, Assembler::parity);
|
||||||
int parity_disp = -1;
|
int parity_disp = -1;
|
||||||
if ($cop$$cmpcode == Assembler::notEqual) {
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
|
||||||
} else if ($cop$$cmpcode == Assembler::equal) {
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
parity_disp = 2;
|
parity_disp = 2;
|
||||||
} else {
|
} else {
|
||||||
@ -12516,7 +12482,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
|||||||
}
|
}
|
||||||
emit_d8(cbuf, parity_disp);
|
emit_d8(cbuf, parity_disp);
|
||||||
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
||||||
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
|
||||||
emit_d8(cbuf, disp);
|
emit_d8(cbuf, disp);
|
||||||
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
|
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
|
||||||
|
@ -230,7 +230,8 @@ int generateJvmOffsets(GEN_variant gen_variant) {
|
|||||||
|
|
||||||
GEN_OFFS(CodeBlob, _name);
|
GEN_OFFS(CodeBlob, _name);
|
||||||
GEN_OFFS(CodeBlob, _header_size);
|
GEN_OFFS(CodeBlob, _header_size);
|
||||||
GEN_OFFS(CodeBlob, _instructions_offset);
|
GEN_OFFS(CodeBlob, _content_offset);
|
||||||
|
GEN_OFFS(CodeBlob, _code_offset);
|
||||||
GEN_OFFS(CodeBlob, _data_offset);
|
GEN_OFFS(CodeBlob, _data_offset);
|
||||||
GEN_OFFS(CodeBlob, _frame_size);
|
GEN_OFFS(CodeBlob, _frame_size);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -124,7 +124,7 @@ typedef struct Nmethod_t {
|
|||||||
uint64_t pc_desc;
|
uint64_t pc_desc;
|
||||||
|
|
||||||
int32_t orig_pc_offset; /* _orig_pc_offset */
|
int32_t orig_pc_offset; /* _orig_pc_offset */
|
||||||
int32_t instrs_beg; /* _instructions_offset */
|
int32_t instrs_beg; /* _code_offset */
|
||||||
int32_t instrs_end;
|
int32_t instrs_end;
|
||||||
int32_t deopt_beg; /* _deoptimize_offset */
|
int32_t deopt_beg; /* _deoptimize_offset */
|
||||||
int32_t scopes_data_beg; /* _scopes_data_offset */
|
int32_t scopes_data_beg; /* _scopes_data_offset */
|
||||||
@ -587,7 +587,7 @@ static int nmethod_info(Nmethod_t *N)
|
|||||||
fprintf(stderr, "\t nmethod_info: BEGIN \n");
|
fprintf(stderr, "\t nmethod_info: BEGIN \n");
|
||||||
|
|
||||||
/* Instructions */
|
/* Instructions */
|
||||||
err = ps_pread(J->P, nm + OFFSET_CodeBlob_instructions_offset, &N->instrs_beg, SZ32);
|
err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32);
|
||||||
CHECK_FAIL(err);
|
CHECK_FAIL(err);
|
||||||
err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
|
err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
|
||||||
CHECK_FAIL(err);
|
CHECK_FAIL(err);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -149,8 +149,8 @@ bool os::register_code_area(char *low, char *high) {
|
|||||||
// If we are using Vectored Exceptions we don't need this registration
|
// If we are using Vectored Exceptions we don't need this registration
|
||||||
if (UseVectoredExceptions) return true;
|
if (UseVectoredExceptions) return true;
|
||||||
|
|
||||||
BufferBlob* b = BufferBlob::create("CodeCache Exception Handler", sizeof (DynamicCodeData));
|
BufferBlob* blob = BufferBlob::create("CodeCache Exception Handler", sizeof(DynamicCodeData));
|
||||||
CodeBuffer cb(b->instructions_begin(), b->instructions_size());
|
CodeBuffer cb(blob);
|
||||||
MacroAssembler* masm = new MacroAssembler(&cb);
|
MacroAssembler* masm = new MacroAssembler(&cb);
|
||||||
pDCD = (pDynamicCodeData) masm->pc();
|
pDCD = (pDynamicCodeData) masm->pc();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -141,8 +141,7 @@ source %{
|
|||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
// emit an interrupt that is caught by the debugger
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
void emit_break(CodeBuffer &cbuf) {
|
||||||
*(cbuf.code_end()) = (unsigned char)(0xcc);
|
cbuf.insts()->emit_int8((unsigned char) 0xcc);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -144,8 +144,7 @@ int MachCallRuntimeNode::ret_addr_offset()
|
|||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
// emit an interrupt that is caught by the debugger
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
void emit_break(CodeBuffer &cbuf) {
|
||||||
*(cbuf.code_end()) = (unsigned char)(0xcc);
|
cbuf.insts()->emit_int8((unsigned char) 0xcc);
|
||||||
cbuf.set_code_end(cbuf.code_end() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
|
@ -2482,7 +2482,7 @@ void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save current instruction's starting address (helps with relocation).
|
// Save current instruction's starting address (helps with relocation).
|
||||||
fprintf( fp, " cbuf.set_inst_mark();\n");
|
fprintf(fp, " cbuf.set_insts_mark();\n");
|
||||||
|
|
||||||
// // // idx0 is only needed for syntactic purposes and only by "storeSSI"
|
// // // idx0 is only needed for syntactic purposes and only by "storeSSI"
|
||||||
// fprintf( fp, " unsigned idx0 = 0;\n");
|
// fprintf( fp, " unsigned idx0 = 0;\n");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -74,12 +74,11 @@
|
|||||||
|
|
||||||
typedef CodeBuffer::csize_t csize_t; // file-local definition
|
typedef CodeBuffer::csize_t csize_t; // file-local definition
|
||||||
|
|
||||||
// external buffer, in a predefined CodeBlob or other buffer area
|
// External buffer, in a predefined CodeBlob.
|
||||||
// Important: The code_start must be taken exactly, and not realigned.
|
// Important: The code_start must be taken exactly, and not realigned.
|
||||||
CodeBuffer::CodeBuffer(address code_start, csize_t code_size) {
|
CodeBuffer::CodeBuffer(CodeBlob* blob) {
|
||||||
assert(code_start != NULL, "sanity");
|
|
||||||
initialize_misc("static buffer");
|
initialize_misc("static buffer");
|
||||||
initialize(code_start, code_size);
|
initialize(blob->content_begin(), blob->content_size());
|
||||||
assert(verify_section_allocation(), "initial use of buffer OK");
|
assert(verify_section_allocation(), "initial use of buffer OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) {
|
|||||||
// Set up various pointers into the blob.
|
// Set up various pointers into the blob.
|
||||||
initialize(_total_start, _total_size);
|
initialize(_total_start, _total_size);
|
||||||
|
|
||||||
assert((uintptr_t)code_begin() % CodeEntryAlignment == 0, "instruction start not code entry aligned");
|
assert((uintptr_t)insts_begin() % CodeEntryAlignment == 0, "instruction start not code entry aligned");
|
||||||
|
|
||||||
pd_initialize();
|
pd_initialize();
|
||||||
|
|
||||||
@ -144,13 +143,6 @@ void CodeBuffer::initialize_oop_recorder(OopRecorder* r) {
|
|||||||
|
|
||||||
void CodeBuffer::initialize_section_size(CodeSection* cs, csize_t size) {
|
void CodeBuffer::initialize_section_size(CodeSection* cs, csize_t size) {
|
||||||
assert(cs != &_insts, "insts is the memory provider, not the consumer");
|
assert(cs != &_insts, "insts is the memory provider, not the consumer");
|
||||||
#ifdef ASSERT
|
|
||||||
for (int n = (int)SECT_INSTS+1; n < (int)SECT_LIMIT; n++) {
|
|
||||||
CodeSection* prevCS = code_section(n);
|
|
||||||
if (prevCS == cs) break;
|
|
||||||
assert(!prevCS->is_allocated(), "section allocation must be in reverse order");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
csize_t slop = CodeSection::end_slop(); // margin between sections
|
csize_t slop = CodeSection::end_slop(); // margin between sections
|
||||||
int align = cs->alignment();
|
int align = cs->alignment();
|
||||||
assert(is_power_of_2(align), "sanity");
|
assert(is_power_of_2(align), "sanity");
|
||||||
@ -192,21 +184,21 @@ void CodeBuffer::freeze_section(CodeSection* cs) {
|
|||||||
void CodeBuffer::set_blob(BufferBlob* blob) {
|
void CodeBuffer::set_blob(BufferBlob* blob) {
|
||||||
_blob = blob;
|
_blob = blob;
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
address start = blob->instructions_begin();
|
address start = blob->content_begin();
|
||||||
address end = blob->instructions_end();
|
address end = blob->content_end();
|
||||||
// Round up the starting address.
|
// Round up the starting address.
|
||||||
int align = _insts.alignment();
|
int align = _insts.alignment();
|
||||||
start += (-(intptr_t)start) & (align-1);
|
start += (-(intptr_t)start) & (align-1);
|
||||||
_total_start = start;
|
_total_start = start;
|
||||||
_total_size = end - start;
|
_total_size = end - start;
|
||||||
} else {
|
} else {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// Clean out dangling pointers.
|
// Clean out dangling pointers.
|
||||||
_total_start = badAddress;
|
_total_start = badAddress;
|
||||||
|
_consts._start = _consts._end = badAddress;
|
||||||
_insts._start = _insts._end = badAddress;
|
_insts._start = _insts._end = badAddress;
|
||||||
_stubs._start = _stubs._end = badAddress;
|
_stubs._start = _stubs._end = badAddress;
|
||||||
_consts._start = _consts._end = badAddress;
|
#endif //ASSERT
|
||||||
#endif //ASSERT
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,9 +214,9 @@ const char* CodeBuffer::code_section_name(int n) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
#else //PRODUCT
|
#else //PRODUCT
|
||||||
switch (n) {
|
switch (n) {
|
||||||
|
case SECT_CONSTS: return "consts";
|
||||||
case SECT_INSTS: return "insts";
|
case SECT_INSTS: return "insts";
|
||||||
case SECT_STUBS: return "stubs";
|
case SECT_STUBS: return "stubs";
|
||||||
case SECT_CONSTS: return "consts";
|
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
#endif //PRODUCT
|
#endif //PRODUCT
|
||||||
@ -422,21 +414,21 @@ void CodeSection::expand_locs(int new_capacity) {
|
|||||||
/// The pattern is the same for all functions.
|
/// The pattern is the same for all functions.
|
||||||
/// We iterate over all the sections, padding each to alignment.
|
/// We iterate over all the sections, padding each to alignment.
|
||||||
|
|
||||||
csize_t CodeBuffer::total_code_size() const {
|
csize_t CodeBuffer::total_content_size() const {
|
||||||
csize_t code_size_so_far = 0;
|
csize_t size_so_far = 0;
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
||||||
const CodeSection* cs = code_section(n);
|
const CodeSection* cs = code_section(n);
|
||||||
if (cs->is_empty()) continue; // skip trivial section
|
if (cs->is_empty()) continue; // skip trivial section
|
||||||
code_size_so_far = cs->align_at_start(code_size_so_far);
|
size_so_far = cs->align_at_start(size_so_far);
|
||||||
code_size_so_far += cs->size();
|
size_so_far += cs->size();
|
||||||
}
|
}
|
||||||
return code_size_so_far;
|
return size_so_far;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
|
void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
|
||||||
address buf = dest->_total_start;
|
address buf = dest->_total_start;
|
||||||
csize_t buf_offset = 0;
|
csize_t buf_offset = 0;
|
||||||
assert(dest->_total_size >= total_code_size(), "must be big enough");
|
assert(dest->_total_size >= total_content_size(), "must be big enough");
|
||||||
|
|
||||||
{
|
{
|
||||||
// not sure why this is here, but why not...
|
// not sure why this is here, but why not...
|
||||||
@ -446,12 +438,11 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
|
|||||||
|
|
||||||
const CodeSection* prev_cs = NULL;
|
const CodeSection* prev_cs = NULL;
|
||||||
CodeSection* prev_dest_cs = NULL;
|
CodeSection* prev_dest_cs = NULL;
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
|
||||||
|
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
|
||||||
// figure compact layout of each section
|
// figure compact layout of each section
|
||||||
const CodeSection* cs = code_section(n);
|
const CodeSection* cs = code_section(n);
|
||||||
address cstart = cs->start();
|
csize_t csize = cs->size();
|
||||||
address cend = cs->end();
|
|
||||||
csize_t csize = cend - cstart;
|
|
||||||
|
|
||||||
CodeSection* dest_cs = dest->code_section(n);
|
CodeSection* dest_cs = dest->code_section(n);
|
||||||
if (!cs->is_empty()) {
|
if (!cs->is_empty()) {
|
||||||
@ -464,7 +455,7 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
|
|||||||
prev_dest_cs->_limit += padding;
|
prev_dest_cs->_limit += padding;
|
||||||
}
|
}
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (prev_cs != NULL && prev_cs->is_frozen() && n < SECT_CONSTS) {
|
if (prev_cs != NULL && prev_cs->is_frozen() && n < (SECT_LIMIT - 1)) {
|
||||||
// Make sure the ends still match up.
|
// Make sure the ends still match up.
|
||||||
// This is important because a branch in a frozen section
|
// This is important because a branch in a frozen section
|
||||||
// might target code in a following section, via a Label,
|
// might target code in a following section, via a Label,
|
||||||
@ -489,33 +480,29 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Done calculating sections; did it come out to the right end?
|
// Done calculating sections; did it come out to the right end?
|
||||||
assert(buf_offset == total_code_size(), "sanity");
|
assert(buf_offset == total_content_size(), "sanity");
|
||||||
assert(dest->verify_section_allocation(), "final configuration works");
|
assert(dest->verify_section_allocation(), "final configuration works");
|
||||||
}
|
}
|
||||||
|
|
||||||
csize_t CodeBuffer::total_offset_of(address addr) const {
|
csize_t CodeBuffer::total_offset_of(CodeSection* cs) const {
|
||||||
csize_t code_size_so_far = 0;
|
csize_t size_so_far = 0;
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
|
||||||
const CodeSection* cs = code_section(n);
|
const CodeSection* cur_cs = code_section(n);
|
||||||
if (!cs->is_empty()) {
|
if (!cur_cs->is_empty()) {
|
||||||
code_size_so_far = cs->align_at_start(code_size_so_far);
|
size_so_far = cur_cs->align_at_start(size_so_far);
|
||||||
}
|
}
|
||||||
if (cs->contains2(addr)) {
|
if (cur_cs->index() == cs->index()) {
|
||||||
return code_size_so_far + (addr - cs->start());
|
return size_so_far;
|
||||||
}
|
}
|
||||||
code_size_so_far += cs->size();
|
size_so_far += cur_cs->size();
|
||||||
}
|
}
|
||||||
#ifndef PRODUCT
|
|
||||||
tty->print_cr("Dangling address " PTR_FORMAT " in:", addr);
|
|
||||||
((CodeBuffer*)this)->print();
|
|
||||||
#endif
|
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
csize_t CodeBuffer::total_relocation_size() const {
|
csize_t CodeBuffer::total_relocation_size() const {
|
||||||
csize_t lsize = copy_relocations_to(NULL); // dry run only
|
csize_t lsize = copy_relocations_to(NULL); // dry run only
|
||||||
csize_t csize = total_code_size();
|
csize_t csize = total_content_size();
|
||||||
csize_t total = RelocIterator::locs_and_index_size(csize, lsize);
|
csize_t total = RelocIterator::locs_and_index_size(csize, lsize);
|
||||||
return (csize_t) align_size_up(total, HeapWordSize);
|
return (csize_t) align_size_up(total, HeapWordSize);
|
||||||
}
|
}
|
||||||
@ -534,7 +521,7 @@ csize_t CodeBuffer::copy_relocations_to(CodeBlob* dest) const {
|
|||||||
|
|
||||||
csize_t code_end_so_far = 0;
|
csize_t code_end_so_far = 0;
|
||||||
csize_t code_point_so_far = 0;
|
csize_t code_point_so_far = 0;
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
for (int n = (int) SECT_FIRST; n < (int)SECT_LIMIT; n++) {
|
||||||
// pull relocs out of each section
|
// pull relocs out of each section
|
||||||
const CodeSection* cs = code_section(n);
|
const CodeSection* cs = code_section(n);
|
||||||
assert(!(cs->is_empty() && cs->locs_count() > 0), "sanity");
|
assert(!(cs->is_empty() && cs->locs_count() > 0), "sanity");
|
||||||
@ -601,7 +588,7 @@ csize_t CodeBuffer::copy_relocations_to(CodeBlob* dest) const {
|
|||||||
buf_offset += sizeof(relocInfo);
|
buf_offset += sizeof(relocInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(code_end_so_far == total_code_size(), "sanity");
|
assert(code_end_so_far == total_content_size(), "sanity");
|
||||||
|
|
||||||
// Account for index:
|
// Account for index:
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
@ -621,9 +608,8 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
|
|||||||
}
|
}
|
||||||
#endif //PRODUCT
|
#endif //PRODUCT
|
||||||
|
|
||||||
CodeBuffer dest(dest_blob->instructions_begin(),
|
CodeBuffer dest(dest_blob);
|
||||||
dest_blob->instructions_size());
|
assert(dest_blob->content_size() >= total_content_size(), "good sizing");
|
||||||
assert(dest_blob->instructions_size() >= total_code_size(), "good sizing");
|
|
||||||
this->compute_final_layout(&dest);
|
this->compute_final_layout(&dest);
|
||||||
relocate_code_to(&dest);
|
relocate_code_to(&dest);
|
||||||
|
|
||||||
@ -631,18 +617,20 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
|
|||||||
dest_blob->set_comments(_comments);
|
dest_blob->set_comments(_comments);
|
||||||
|
|
||||||
// Done moving code bytes; were they the right size?
|
// Done moving code bytes; were they the right size?
|
||||||
assert(round_to(dest.total_code_size(), oopSize) == dest_blob->instructions_size(), "sanity");
|
assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity");
|
||||||
|
|
||||||
// Flush generated code
|
// Flush generated code
|
||||||
ICache::invalidate_range(dest_blob->instructions_begin(),
|
ICache::invalidate_range(dest_blob->code_begin(), dest_blob->code_size());
|
||||||
dest_blob->instructions_size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all my code into another code buffer.
|
// Move all my code into another code buffer. Consult applicable
|
||||||
// Consult applicable relocs to repair embedded addresses.
|
// relocs to repair embedded addresses. The layout in the destination
|
||||||
|
// CodeBuffer is different to the source CodeBuffer: the destination
|
||||||
|
// CodeBuffer gets the final layout (consts, insts, stubs in order of
|
||||||
|
// ascending address).
|
||||||
void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
|
void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
|
||||||
DEBUG_ONLY(address dest_end = dest->_total_start + dest->_total_size);
|
DEBUG_ONLY(address dest_end = dest->_total_start + dest->_total_size);
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
|
||||||
// pull code out of each section
|
// pull code out of each section
|
||||||
const CodeSection* cs = code_section(n);
|
const CodeSection* cs = code_section(n);
|
||||||
if (cs->is_empty()) continue; // skip trivial section
|
if (cs->is_empty()) continue; // skip trivial section
|
||||||
@ -684,20 +672,19 @@ csize_t CodeBuffer::figure_expanded_capacities(CodeSection* which_cs,
|
|||||||
csize_t* new_capacity) {
|
csize_t* new_capacity) {
|
||||||
csize_t new_total_cap = 0;
|
csize_t new_total_cap = 0;
|
||||||
|
|
||||||
int prev_n = -1;
|
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
|
||||||
const CodeSection* sect = code_section(n);
|
const CodeSection* sect = code_section(n);
|
||||||
|
|
||||||
if (!sect->is_empty()) {
|
if (!sect->is_empty()) {
|
||||||
// Compute initial padding; assign it to the previous non-empty guy.
|
// Compute initial padding; assign it to the previous section,
|
||||||
// Cf. compute_final_layout.
|
// even if it's empty (e.g. consts section can be empty).
|
||||||
|
// Cf. compute_final_layout
|
||||||
csize_t padding = sect->align_at_start(new_total_cap) - new_total_cap;
|
csize_t padding = sect->align_at_start(new_total_cap) - new_total_cap;
|
||||||
if (padding != 0) {
|
if (padding != 0) {
|
||||||
new_total_cap += padding;
|
new_total_cap += padding;
|
||||||
assert(prev_n >= 0, "sanity");
|
assert(n - 1 >= SECT_FIRST, "sanity");
|
||||||
new_capacity[prev_n] += padding;
|
new_capacity[n - 1] += padding;
|
||||||
}
|
}
|
||||||
prev_n = n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
csize_t exp = sect->size(); // 100% increase
|
csize_t exp = sect->size(); // 100% increase
|
||||||
@ -777,11 +764,11 @@ void CodeBuffer::expand(CodeSection* which_cs, csize_t amount) {
|
|||||||
this->_before_expand = bxp;
|
this->_before_expand = bxp;
|
||||||
|
|
||||||
// Give each section its required (expanded) capacity.
|
// Give each section its required (expanded) capacity.
|
||||||
for (int n = (int)SECT_LIMIT-1; n >= SECT_INSTS; n--) {
|
for (int n = (int)SECT_LIMIT-1; n >= SECT_FIRST; n--) {
|
||||||
CodeSection* cb_sect = cb.code_section(n);
|
CodeSection* cb_sect = cb.code_section(n);
|
||||||
CodeSection* this_sect = code_section(n);
|
CodeSection* this_sect = code_section(n);
|
||||||
if (new_capacity[n] == 0) continue; // already nulled out
|
if (new_capacity[n] == 0) continue; // already nulled out
|
||||||
if (n > SECT_INSTS) {
|
if (n != SECT_INSTS) {
|
||||||
cb.initialize_section_size(cb_sect, new_capacity[n]);
|
cb.initialize_section_size(cb_sect, new_capacity[n]);
|
||||||
}
|
}
|
||||||
assert(cb_sect->capacity() >= new_capacity[n], "big enough");
|
assert(cb_sect->capacity() >= new_capacity[n], "big enough");
|
||||||
@ -844,20 +831,25 @@ bool CodeBuffer::verify_section_allocation() {
|
|||||||
if (tstart == badAddress) return true; // smashed by set_blob(NULL)
|
if (tstart == badAddress) return true; // smashed by set_blob(NULL)
|
||||||
address tend = tstart + _total_size;
|
address tend = tstart + _total_size;
|
||||||
if (_blob != NULL) {
|
if (_blob != NULL) {
|
||||||
assert(tstart >= _blob->instructions_begin(), "sanity");
|
assert(tstart >= _blob->content_begin(), "sanity");
|
||||||
assert(tend <= _blob->instructions_end(), "sanity");
|
assert(tend <= _blob->content_end(), "sanity");
|
||||||
}
|
}
|
||||||
address tcheck = tstart; // advancing pointer to verify disjointness
|
// Verify disjointness.
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
|
||||||
CodeSection* sect = code_section(n);
|
CodeSection* sect = code_section(n);
|
||||||
if (!sect->is_allocated()) continue;
|
if (!sect->is_allocated() || sect->is_empty()) continue;
|
||||||
assert(sect->start() >= tcheck, "sanity");
|
assert((intptr_t)sect->start() % sect->alignment() == 0
|
||||||
tcheck = sect->start();
|
|
||||||
assert((intptr_t)tcheck % sect->alignment() == 0
|
|
||||||
|| sect->is_empty() || _blob == NULL,
|
|| sect->is_empty() || _blob == NULL,
|
||||||
"start is aligned");
|
"start is aligned");
|
||||||
assert(sect->end() >= tcheck, "sanity");
|
for (int m = (int) SECT_FIRST; m < (int) SECT_LIMIT; m++) {
|
||||||
assert(sect->end() <= tend, "sanity");
|
CodeSection* other = code_section(m);
|
||||||
|
if (!other->is_allocated() || other == sect) continue;
|
||||||
|
assert(!other->contains(sect->start() ), "sanity");
|
||||||
|
// limit is an exclusive address and can be the start of another
|
||||||
|
// section.
|
||||||
|
assert(!other->contains(sect->limit() - 1), "sanity");
|
||||||
|
}
|
||||||
|
assert(sect->end() <= tend, "sanity");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -981,13 +973,13 @@ void CodeComments::free() {
|
|||||||
|
|
||||||
|
|
||||||
void CodeBuffer::decode() {
|
void CodeBuffer::decode() {
|
||||||
Disassembler::decode(decode_begin(), code_end());
|
Disassembler::decode(decode_begin(), insts_end());
|
||||||
_decode_begin = code_end();
|
_decode_begin = insts_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CodeBuffer::skip_decode() {
|
void CodeBuffer::skip_decode() {
|
||||||
_decode_begin = code_end();
|
_decode_begin = insts_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,6 +186,12 @@ class CodeSection VALUE_OBJ_CLASS_SPEC {
|
|||||||
_locs_point = pc;
|
_locs_point = pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Code emission
|
||||||
|
void emit_int8 (int8_t x) { *((int8_t*) end()) = x; set_end(end() + 1); }
|
||||||
|
void emit_int16(int16_t x) { *((int16_t*) end()) = x; set_end(end() + 2); }
|
||||||
|
void emit_int32(int32_t x) { *((int32_t*) end()) = x; set_end(end() + 4); }
|
||||||
|
void emit_int64(int64_t x) { *((int64_t*) end()) = x; set_end(end() + 8); }
|
||||||
|
|
||||||
// Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.)
|
// Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.)
|
||||||
void initialize_shared_locs(relocInfo* buf, int length);
|
void initialize_shared_locs(relocInfo* buf, int length);
|
||||||
|
|
||||||
@ -283,10 +289,12 @@ class CodeBuffer: public StackObj {
|
|||||||
public:
|
public:
|
||||||
typedef int csize_t; // code size type; would be size_t except for history
|
typedef int csize_t; // code size type; would be size_t except for history
|
||||||
enum {
|
enum {
|
||||||
// Here is the list of all possible sections, in order of ascending address.
|
// Here is the list of all possible sections. The order reflects
|
||||||
|
// the final layout.
|
||||||
|
SECT_FIRST = 0,
|
||||||
|
SECT_CONSTS = SECT_FIRST, // Non-instruction data: Floats, jump tables, etc.
|
||||||
SECT_INSTS, // Executable instructions.
|
SECT_INSTS, // Executable instructions.
|
||||||
SECT_STUBS, // Outbound trampolines for supporting call sites.
|
SECT_STUBS, // Outbound trampolines for supporting call sites.
|
||||||
SECT_CONSTS, // Non-instruction data: Floats, jump tables, etc.
|
|
||||||
SECT_LIMIT, SECT_NONE = -1
|
SECT_LIMIT, SECT_NONE = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -298,9 +306,9 @@ class CodeBuffer: public StackObj {
|
|||||||
|
|
||||||
const char* _name;
|
const char* _name;
|
||||||
|
|
||||||
|
CodeSection _consts; // constants, jump tables
|
||||||
CodeSection _insts; // instructions (the main section)
|
CodeSection _insts; // instructions (the main section)
|
||||||
CodeSection _stubs; // stubs (call site support), deopt, exception handling
|
CodeSection _stubs; // stubs (call site support), deopt, exception handling
|
||||||
CodeSection _consts; // constants, jump tables
|
|
||||||
|
|
||||||
CodeBuffer* _before_expand; // dead buffer, from before the last expansion
|
CodeBuffer* _before_expand; // dead buffer, from before the last expansion
|
||||||
|
|
||||||
@ -328,9 +336,9 @@ class CodeBuffer: public StackObj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initialize(address code_start, csize_t code_size) {
|
void initialize(address code_start, csize_t code_size) {
|
||||||
|
_consts.initialize_outer(this, SECT_CONSTS);
|
||||||
_insts.initialize_outer(this, SECT_INSTS);
|
_insts.initialize_outer(this, SECT_INSTS);
|
||||||
_stubs.initialize_outer(this, SECT_STUBS);
|
_stubs.initialize_outer(this, SECT_STUBS);
|
||||||
_consts.initialize_outer(this, SECT_CONSTS);
|
|
||||||
_total_start = code_start;
|
_total_start = code_start;
|
||||||
_total_size = code_size;
|
_total_size = code_size;
|
||||||
// Initialize the main section:
|
// Initialize the main section:
|
||||||
@ -374,9 +382,17 @@ class CodeBuffer: public StackObj {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// (1) code buffer referring to pre-allocated instruction memory
|
// (1) code buffer referring to pre-allocated instruction memory
|
||||||
CodeBuffer(address code_start, csize_t code_size);
|
CodeBuffer(address code_start, csize_t code_size) {
|
||||||
|
assert(code_start != NULL, "sanity");
|
||||||
|
initialize_misc("static buffer");
|
||||||
|
initialize(code_start, code_size);
|
||||||
|
assert(verify_section_allocation(), "initial use of buffer OK");
|
||||||
|
}
|
||||||
|
|
||||||
// (2) code buffer allocating codeBlob memory for code & relocation
|
// (2) CodeBuffer referring to pre-allocated CodeBlob.
|
||||||
|
CodeBuffer(CodeBlob* blob);
|
||||||
|
|
||||||
|
// (3) code buffer allocating codeBlob memory for code & relocation
|
||||||
// info but with lazy initialization. The name must be something
|
// info but with lazy initialization. The name must be something
|
||||||
// informative.
|
// informative.
|
||||||
CodeBuffer(const char* name) {
|
CodeBuffer(const char* name) {
|
||||||
@ -384,7 +400,7 @@ class CodeBuffer: public StackObj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// (3) code buffer allocating codeBlob memory for code & relocation
|
// (4) code buffer allocating codeBlob memory for code & relocation
|
||||||
// info. The name must be something informative and code_size must
|
// info. The name must be something informative and code_size must
|
||||||
// include both code and stubs sizes.
|
// include both code and stubs sizes.
|
||||||
CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) {
|
CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) {
|
||||||
@ -394,22 +410,22 @@ class CodeBuffer: public StackObj {
|
|||||||
|
|
||||||
~CodeBuffer();
|
~CodeBuffer();
|
||||||
|
|
||||||
// Initialize a CodeBuffer constructed using constructor 2. Using
|
// Initialize a CodeBuffer constructed using constructor 3. Using
|
||||||
// constructor 3 is equivalent to calling constructor 2 and then
|
// constructor 4 is equivalent to calling constructor 3 and then
|
||||||
// calling this method. It's been factored out for convenience of
|
// calling this method. It's been factored out for convenience of
|
||||||
// construction.
|
// construction.
|
||||||
void initialize(csize_t code_size, csize_t locs_size);
|
void initialize(csize_t code_size, csize_t locs_size);
|
||||||
|
|
||||||
|
CodeSection* consts() { return &_consts; }
|
||||||
CodeSection* insts() { return &_insts; }
|
CodeSection* insts() { return &_insts; }
|
||||||
CodeSection* stubs() { return &_stubs; }
|
CodeSection* stubs() { return &_stubs; }
|
||||||
CodeSection* consts() { return &_consts; }
|
|
||||||
|
|
||||||
// present sections in order; return NULL at end; insts is #0, etc.
|
// present sections in order; return NULL at end; consts is #0, etc.
|
||||||
CodeSection* code_section(int n) {
|
CodeSection* code_section(int n) {
|
||||||
// This makes the slightly questionable but portable assumption that
|
// This makes the slightly questionable but portable assumption
|
||||||
// the various members (_insts, _stubs, etc.) are adjacent in the
|
// that the various members (_consts, _insts, _stubs, etc.) are
|
||||||
// layout of CodeBuffer.
|
// adjacent in the layout of CodeBuffer.
|
||||||
CodeSection* cs = &_insts + n;
|
CodeSection* cs = &_consts + n;
|
||||||
assert(cs->index() == n || !cs->is_allocated(), "sanity");
|
assert(cs->index() == n || !cs->is_allocated(), "sanity");
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
@ -438,40 +454,41 @@ class CodeBuffer: public StackObj {
|
|||||||
void free_blob(); // Free the blob, if we own one.
|
void free_blob(); // Free the blob, if we own one.
|
||||||
|
|
||||||
// Properties relative to the insts section:
|
// Properties relative to the insts section:
|
||||||
address code_begin() const { return _insts.start(); }
|
address insts_begin() const { return _insts.start(); }
|
||||||
address code_end() const { return _insts.end(); }
|
address insts_end() const { return _insts.end(); }
|
||||||
void set_code_end(address end) { _insts.set_end(end); }
|
void set_insts_end(address end) { _insts.set_end(end); }
|
||||||
address code_limit() const { return _insts.limit(); }
|
address insts_limit() const { return _insts.limit(); }
|
||||||
address inst_mark() const { return _insts.mark(); }
|
address insts_mark() const { return _insts.mark(); }
|
||||||
void set_inst_mark() { _insts.set_mark(); }
|
void set_insts_mark() { _insts.set_mark(); }
|
||||||
void clear_inst_mark() { _insts.clear_mark(); }
|
void clear_insts_mark() { _insts.clear_mark(); }
|
||||||
|
|
||||||
// is there anything in the buffer other than the current section?
|
// is there anything in the buffer other than the current section?
|
||||||
bool is_pure() const { return code_size() == total_code_size(); }
|
bool is_pure() const { return insts_size() == total_content_size(); }
|
||||||
|
|
||||||
// size in bytes of output so far in the insts sections
|
// size in bytes of output so far in the insts sections
|
||||||
csize_t code_size() const { return _insts.size(); }
|
csize_t insts_size() const { return _insts.size(); }
|
||||||
|
|
||||||
// same as code_size(), except that it asserts there is no non-code here
|
// same as insts_size(), except that it asserts there is no non-code here
|
||||||
csize_t pure_code_size() const { assert(is_pure(), "no non-code");
|
csize_t pure_insts_size() const { assert(is_pure(), "no non-code");
|
||||||
return code_size(); }
|
return insts_size(); }
|
||||||
// capacity in bytes of the insts sections
|
// capacity in bytes of the insts sections
|
||||||
csize_t code_capacity() const { return _insts.capacity(); }
|
csize_t insts_capacity() const { return _insts.capacity(); }
|
||||||
|
|
||||||
// number of bytes remaining in the insts section
|
// number of bytes remaining in the insts section
|
||||||
csize_t code_remaining() const { return _insts.remaining(); }
|
csize_t insts_remaining() const { return _insts.remaining(); }
|
||||||
|
|
||||||
// is a given address in the insts section? (2nd version is end-inclusive)
|
// is a given address in the insts section? (2nd version is end-inclusive)
|
||||||
bool code_contains(address pc) const { return _insts.contains(pc); }
|
bool insts_contains(address pc) const { return _insts.contains(pc); }
|
||||||
bool code_contains2(address pc) const { return _insts.contains2(pc); }
|
bool insts_contains2(address pc) const { return _insts.contains2(pc); }
|
||||||
|
|
||||||
// allocated size of code in all sections, when aligned and concatenated
|
// Allocated size in all sections, when aligned and concatenated
|
||||||
// (this is the eventual state of the code in its final CodeBlob)
|
// (this is the eventual state of the content in its final
|
||||||
csize_t total_code_size() const;
|
// CodeBlob).
|
||||||
|
csize_t total_content_size() const;
|
||||||
|
|
||||||
// combined offset (relative to start of insts) of given address,
|
// Combined offset (relative to start of first section) of given
|
||||||
// as eventually found in the final CodeBlob
|
// section, as eventually found in the final CodeBlob.
|
||||||
csize_t total_offset_of(address addr) const;
|
csize_t total_offset_of(CodeSection* cs) const;
|
||||||
|
|
||||||
// allocated size of all relocation data, including index, rounded up
|
// allocated size of all relocation data, including index, rounded up
|
||||||
csize_t total_relocation_size() const;
|
csize_t total_relocation_size() const;
|
||||||
|
@ -454,8 +454,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
|
|||||||
, _allocator(NULL)
|
, _allocator(NULL)
|
||||||
, _next_id(0)
|
, _next_id(0)
|
||||||
, _next_block_id(0)
|
, _next_block_id(0)
|
||||||
, _code(buffer_blob->instructions_begin(),
|
, _code(buffer_blob)
|
||||||
buffer_blob->instructions_size())
|
|
||||||
, _current_instruction(NULL)
|
, _current_instruction(NULL)
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
, _last_instruction_printed(NULL)
|
, _last_instruction_printed(NULL)
|
||||||
|
@ -118,8 +118,7 @@ void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
|
|||||||
assert(0 <= id && id < number_of_ids, "illegal stub id");
|
assert(0 <= id && id < number_of_ids, "illegal stub id");
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
// create code buffer for code storage
|
// create code buffer for code storage
|
||||||
CodeBuffer code(buffer_blob->instructions_begin(),
|
CodeBuffer code(buffer_blob);
|
||||||
buffer_blob->instructions_size());
|
|
||||||
|
|
||||||
Compilation::setup_code_buffer(&code, 0);
|
Compilation::setup_code_buffer(&code, 0);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -155,7 +155,7 @@ class Runtime1: public AllStatic {
|
|||||||
|
|
||||||
// stubs
|
// stubs
|
||||||
static CodeBlob* blob_for (StubID id);
|
static CodeBlob* blob_for (StubID id);
|
||||||
static address entry_for(StubID id) { return blob_for(id)->instructions_begin(); }
|
static address entry_for(StubID id) { return blob_for(id)->code_begin(); }
|
||||||
static const char* name_for (StubID id);
|
static const char* name_for (StubID id);
|
||||||
static const char* name_for_address(address entry);
|
static const char* name_for_address(address entry);
|
||||||
|
|
||||||
|
@ -92,11 +92,11 @@ public:
|
|||||||
empty_map.clear();
|
empty_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentMap raw_pop() { assert(_stack_height > 0, "stack underflow"); return _stack[--_stack_height]; }
|
ArgumentMap raw_pop() { guarantee(_stack_height > 0, "stack underflow"); return _stack[--_stack_height]; }
|
||||||
ArgumentMap apop() { return raw_pop(); }
|
ArgumentMap apop() { return raw_pop(); }
|
||||||
void spop() { raw_pop(); }
|
void spop() { raw_pop(); }
|
||||||
void lpop() { spop(); spop(); }
|
void lpop() { spop(); spop(); }
|
||||||
void raw_push(ArgumentMap i) { assert(_stack_height < _max_stack, "stack overflow"); _stack[_stack_height++] = i; }
|
void raw_push(ArgumentMap i) { guarantee(_stack_height < _max_stack, "stack overflow"); _stack[_stack_height++] = i; }
|
||||||
void apush(ArgumentMap i) { raw_push(i); }
|
void apush(ArgumentMap i) { raw_push(i); }
|
||||||
void spush() { raw_push(empty_map); }
|
void spush() { raw_push(empty_map); }
|
||||||
void lpush() { spush(); spush(); }
|
void lpush() { spush(); spush(); }
|
||||||
@ -365,12 +365,19 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl
|
|||||||
case Bytecodes::_ldc:
|
case Bytecodes::_ldc:
|
||||||
case Bytecodes::_ldc_w:
|
case Bytecodes::_ldc_w:
|
||||||
case Bytecodes::_ldc2_w:
|
case Bytecodes::_ldc2_w:
|
||||||
if (type2size[s.get_constant().basic_type()] == 1) {
|
{
|
||||||
state.spush();
|
// Avoid calling get_constant() which will try to allocate
|
||||||
} else {
|
// unloaded constant. We need only constant's type.
|
||||||
|
int index = s.get_constant_pool_index();
|
||||||
|
constantTag tag = s.get_constant_pool_tag(index);
|
||||||
|
if (tag.is_long() || tag.is_double()) {
|
||||||
|
// Only longs and doubles use 2 stack slots.
|
||||||
state.lpush();
|
state.lpush();
|
||||||
|
} else {
|
||||||
|
state.spush();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Bytecodes::_aload:
|
case Bytecodes::_aload:
|
||||||
state.apush(state._vars[s.get_index()]);
|
state.apush(state._vars[s.get_index()]);
|
||||||
break;
|
break;
|
||||||
|
@ -922,12 +922,12 @@ bool ciMethod::has_compiled_code() {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciMethod::instructions_size
|
// ciMethod::instructions_size
|
||||||
// This is a rough metric for "fat" methods, compared
|
//
|
||||||
// before inlining with InlineSmallCode.
|
// This is a rough metric for "fat" methods, compared before inlining
|
||||||
// The CodeBlob::instructions_size accessor includes
|
// with InlineSmallCode. The CodeBlob::code_size accessor includes
|
||||||
// junk like exception handler, stubs, and constant table,
|
// junk like exception handler, stubs, and constant table, which are
|
||||||
// which are not highly relevant to an inlined method.
|
// not highly relevant to an inlined method. So we use the more
|
||||||
// So we use the more specific accessor nmethod::code_size.
|
// specific accessor nmethod::insts_size.
|
||||||
int ciMethod::instructions_size() {
|
int ciMethod::instructions_size() {
|
||||||
GUARDED_VM_ENTRY(
|
GUARDED_VM_ENTRY(
|
||||||
nmethod* code = get_methodOop()->code();
|
nmethod* code = get_methodOop()->code();
|
||||||
@ -939,7 +939,7 @@ int ciMethod::instructions_size() {
|
|||||||
(TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
|
(TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return code->code_end() - code->verified_entry_point();
|
return code->insts_end() - code->verified_entry_point();
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) {
|
|||||||
size += round_to(cb->total_relocation_size(), oopSize);
|
size += round_to(cb->total_relocation_size(), oopSize);
|
||||||
// align the size to CodeEntryAlignment
|
// align the size to CodeEntryAlignment
|
||||||
size = align_code_offset(size);
|
size = align_code_offset(size);
|
||||||
size += round_to(cb->total_code_size(), oopSize);
|
size += round_to(cb->total_content_size(), oopSize);
|
||||||
size += round_to(cb->total_oop_size(), oopSize);
|
size += round_to(cb->total_oop_size(), oopSize);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -47,8 +47,8 @@ unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) {
|
|||||||
|
|
||||||
// Creates a simple CodeBlob. Sets up the size of the different regions.
|
// Creates a simple CodeBlob. Sets up the size of the different regions.
|
||||||
CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size) {
|
CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size) {
|
||||||
assert(size == round_to(size, oopSize), "unaligned size");
|
assert(size == round_to(size, oopSize), "unaligned size");
|
||||||
assert(locs_size == round_to(locs_size, oopSize), "unaligned size");
|
assert(locs_size == round_to(locs_size, oopSize), "unaligned size");
|
||||||
assert(header_size == round_to(header_size, oopSize), "unaligned size");
|
assert(header_size == round_to(header_size, oopSize), "unaligned size");
|
||||||
assert(!UseRelocIndex, "no space allocated for reloc index yet");
|
assert(!UseRelocIndex, "no space allocated for reloc index yet");
|
||||||
|
|
||||||
@ -64,7 +64,8 @@ CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_comple
|
|||||||
_frame_complete_offset = frame_complete;
|
_frame_complete_offset = frame_complete;
|
||||||
_header_size = header_size;
|
_header_size = header_size;
|
||||||
_relocation_size = locs_size;
|
_relocation_size = locs_size;
|
||||||
_instructions_offset = align_code_offset(header_size + locs_size);
|
_content_offset = align_code_offset(header_size + _relocation_size);
|
||||||
|
_code_offset = _content_offset;
|
||||||
_data_offset = size;
|
_data_offset = size;
|
||||||
_frame_size = 0;
|
_frame_size = 0;
|
||||||
set_oop_maps(NULL);
|
set_oop_maps(NULL);
|
||||||
@ -82,7 +83,7 @@ CodeBlob::CodeBlob(
|
|||||||
int frame_size,
|
int frame_size,
|
||||||
OopMapSet* oop_maps
|
OopMapSet* oop_maps
|
||||||
) {
|
) {
|
||||||
assert(size == round_to(size, oopSize), "unaligned size");
|
assert(size == round_to(size, oopSize), "unaligned size");
|
||||||
assert(header_size == round_to(header_size, oopSize), "unaligned size");
|
assert(header_size == round_to(header_size, oopSize), "unaligned size");
|
||||||
|
|
||||||
_name = name;
|
_name = name;
|
||||||
@ -90,8 +91,9 @@ CodeBlob::CodeBlob(
|
|||||||
_frame_complete_offset = frame_complete;
|
_frame_complete_offset = frame_complete;
|
||||||
_header_size = header_size;
|
_header_size = header_size;
|
||||||
_relocation_size = round_to(cb->total_relocation_size(), oopSize);
|
_relocation_size = round_to(cb->total_relocation_size(), oopSize);
|
||||||
_instructions_offset = align_code_offset(header_size + _relocation_size);
|
_content_offset = align_code_offset(header_size + _relocation_size);
|
||||||
_data_offset = _instructions_offset + round_to(cb->total_code_size(), oopSize);
|
_code_offset = _content_offset + cb->total_offset_of(cb->insts());
|
||||||
|
_data_offset = _content_offset + round_to(cb->total_content_size(), oopSize);
|
||||||
assert(_data_offset <= size, "codeBlob is too small");
|
assert(_data_offset <= size, "codeBlob is too small");
|
||||||
|
|
||||||
cb->copy_code_and_locs_to(this);
|
cb->copy_code_and_locs_to(this);
|
||||||
@ -127,9 +129,8 @@ void CodeBlob::flush() {
|
|||||||
|
|
||||||
|
|
||||||
OopMap* CodeBlob::oop_map_for_return_address(address return_address) {
|
OopMap* CodeBlob::oop_map_for_return_address(address return_address) {
|
||||||
address pc = return_address ;
|
assert(oop_maps() != NULL, "nope");
|
||||||
assert (oop_maps() != NULL, "nope");
|
return oop_maps()->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
|
||||||
return oop_maps()->find_map_at_offset ((intptr_t) pc - (intptr_t) instructions_begin());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -284,12 +285,12 @@ RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,
|
|||||||
jio_snprintf(stub_id, sizeof(stub_id), "RuntimeStub - %s", stub_name);
|
jio_snprintf(stub_id, sizeof(stub_id), "RuntimeStub - %s", stub_name);
|
||||||
if (PrintStubCode) {
|
if (PrintStubCode) {
|
||||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, stub);
|
tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, stub);
|
||||||
Disassembler::decode(stub->instructions_begin(), stub->instructions_end());
|
Disassembler::decode(stub->code_begin(), stub->code_end());
|
||||||
}
|
}
|
||||||
Forte::register_stub(stub_id, stub->instructions_begin(), stub->instructions_end());
|
Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||||
JvmtiExport::post_dynamic_code_generated(stub_name, stub->instructions_begin(), stub->instructions_end());
|
JvmtiExport::post_dynamic_code_generated(stub_name, stub->code_begin(), stub->code_end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,17 +356,15 @@ DeoptimizationBlob* DeoptimizationBlob::create(
|
|||||||
// Do not hold the CodeCache lock during name formatting.
|
// Do not hold the CodeCache lock during name formatting.
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
char blob_id[256];
|
char blob_id[256];
|
||||||
jio_snprintf(blob_id, sizeof(blob_id), "DeoptimizationBlob@" PTR_FORMAT, blob->instructions_begin());
|
jio_snprintf(blob_id, sizeof(blob_id), "DeoptimizationBlob@" PTR_FORMAT, blob->code_begin());
|
||||||
if (PrintStubCode) {
|
if (PrintStubCode) {
|
||||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||||
Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
|
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||||
}
|
}
|
||||||
Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
|
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||||
JvmtiExport::post_dynamic_code_generated("DeoptimizationBlob",
|
JvmtiExport::post_dynamic_code_generated("DeoptimizationBlob", blob->code_begin(), blob->code_end());
|
||||||
blob->instructions_begin(),
|
|
||||||
blob->instructions_end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,17 +411,15 @@ UncommonTrapBlob* UncommonTrapBlob::create(
|
|||||||
// Do not hold the CodeCache lock during name formatting.
|
// Do not hold the CodeCache lock during name formatting.
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
char blob_id[256];
|
char blob_id[256];
|
||||||
jio_snprintf(blob_id, sizeof(blob_id), "UncommonTrapBlob@" PTR_FORMAT, blob->instructions_begin());
|
jio_snprintf(blob_id, sizeof(blob_id), "UncommonTrapBlob@" PTR_FORMAT, blob->code_begin());
|
||||||
if (PrintStubCode) {
|
if (PrintStubCode) {
|
||||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||||
Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
|
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||||
}
|
}
|
||||||
Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
|
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||||
JvmtiExport::post_dynamic_code_generated("UncommonTrapBlob",
|
JvmtiExport::post_dynamic_code_generated("UncommonTrapBlob", blob->code_begin(), blob->code_end());
|
||||||
blob->instructions_begin(),
|
|
||||||
blob->instructions_end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,17 +468,15 @@ ExceptionBlob* ExceptionBlob::create(
|
|||||||
// We do not need to hold the CodeCache lock during name formatting
|
// We do not need to hold the CodeCache lock during name formatting
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
char blob_id[256];
|
char blob_id[256];
|
||||||
jio_snprintf(blob_id, sizeof(blob_id), "ExceptionBlob@" PTR_FORMAT, blob->instructions_begin());
|
jio_snprintf(blob_id, sizeof(blob_id), "ExceptionBlob@" PTR_FORMAT, blob->code_begin());
|
||||||
if (PrintStubCode) {
|
if (PrintStubCode) {
|
||||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||||
Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
|
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||||
}
|
}
|
||||||
Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
|
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||||
JvmtiExport::post_dynamic_code_generated("ExceptionBlob",
|
JvmtiExport::post_dynamic_code_generated("ExceptionBlob", blob->code_begin(), blob->code_end());
|
||||||
blob->instructions_begin(),
|
|
||||||
blob->instructions_end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,17 +524,15 @@ SafepointBlob* SafepointBlob::create(
|
|||||||
// We do not need to hold the CodeCache lock during name formatting.
|
// We do not need to hold the CodeCache lock during name formatting.
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
char blob_id[256];
|
char blob_id[256];
|
||||||
jio_snprintf(blob_id, sizeof(blob_id), "SafepointBlob@" PTR_FORMAT, blob->instructions_begin());
|
jio_snprintf(blob_id, sizeof(blob_id), "SafepointBlob@" PTR_FORMAT, blob->code_begin());
|
||||||
if (PrintStubCode) {
|
if (PrintStubCode) {
|
||||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||||
Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
|
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||||
}
|
}
|
||||||
Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
|
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||||
JvmtiExport::post_dynamic_code_generated("SafepointBlob",
|
JvmtiExport::post_dynamic_code_generated("SafepointBlob", blob->code_begin(), blob->code_end());
|
||||||
blob->instructions_begin(),
|
|
||||||
blob->instructions_end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
// Layout:
|
// Layout:
|
||||||
// - header
|
// - header
|
||||||
// - relocation
|
// - relocation
|
||||||
// - instruction space
|
// - content space
|
||||||
|
// - instruction space
|
||||||
// - data space
|
// - data space
|
||||||
class DeoptimizationBlob;
|
class DeoptimizationBlob;
|
||||||
|
|
||||||
@ -48,7 +49,8 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||||||
int _size; // total size of CodeBlob in bytes
|
int _size; // total size of CodeBlob in bytes
|
||||||
int _header_size; // size of header (depends on subclass)
|
int _header_size; // size of header (depends on subclass)
|
||||||
int _relocation_size; // size of relocation
|
int _relocation_size; // size of relocation
|
||||||
int _instructions_offset; // offset to where instructions region begins
|
int _content_offset; // offset to where content region begins (this includes consts, insts, stubs)
|
||||||
|
int _code_offset; // offset to where instructions region begins (this includes insts, stubs)
|
||||||
int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have
|
int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have
|
||||||
// not finished setting up their frame. Beware of pc's in
|
// not finished setting up their frame. Beware of pc's in
|
||||||
// that range. There is a similar range(s) on returns
|
// that range. There is a similar range(s) on returns
|
||||||
@ -106,31 +108,36 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||||||
address header_end() const { return ((address) this) + _header_size; };
|
address header_end() const { return ((address) this) + _header_size; };
|
||||||
relocInfo* relocation_begin() const { return (relocInfo*) header_end(); };
|
relocInfo* relocation_begin() const { return (relocInfo*) header_end(); };
|
||||||
relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); }
|
relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); }
|
||||||
address instructions_begin() const { return (address) header_begin() + _instructions_offset; }
|
address content_begin() const { return (address) header_begin() + _content_offset; }
|
||||||
address instructions_end() const { return (address) header_begin() + _data_offset; }
|
address content_end() const { return (address) header_begin() + _data_offset; }
|
||||||
|
address code_begin() const { return (address) header_begin() + _code_offset; }
|
||||||
|
address code_end() const { return (address) header_begin() + _data_offset; }
|
||||||
address data_begin() const { return (address) header_begin() + _data_offset; }
|
address data_begin() const { return (address) header_begin() + _data_offset; }
|
||||||
address data_end() const { return (address) header_begin() + _size; }
|
address data_end() const { return (address) header_begin() + _size; }
|
||||||
|
|
||||||
// Offsets
|
// Offsets
|
||||||
int relocation_offset() const { return _header_size; }
|
int relocation_offset() const { return _header_size; }
|
||||||
int instructions_offset() const { return _instructions_offset; }
|
int content_offset() const { return _content_offset; }
|
||||||
|
int code_offset() const { return _code_offset; }
|
||||||
int data_offset() const { return _data_offset; }
|
int data_offset() const { return _data_offset; }
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
int size() const { return _size; }
|
int size() const { return _size; }
|
||||||
int header_size() const { return _header_size; }
|
int header_size() const { return _header_size; }
|
||||||
int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); }
|
int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); }
|
||||||
int instructions_size() const { return instructions_end() - instructions_begin(); }
|
int content_size() const { return content_end() - content_begin(); }
|
||||||
int data_size() const { return data_end() - data_begin(); }
|
int code_size() const { return code_end() - code_begin(); }
|
||||||
|
int data_size() const { return data_end() - data_begin(); }
|
||||||
|
|
||||||
// Containment
|
// Containment
|
||||||
bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); }
|
bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); }
|
||||||
bool relocation_contains(relocInfo* addr) const{ return relocation_begin() <= addr && addr < relocation_end(); }
|
bool relocation_contains(relocInfo* addr) const{ return relocation_begin() <= addr && addr < relocation_end(); }
|
||||||
bool instructions_contains(address addr) const { return instructions_begin() <= addr && addr < instructions_end(); }
|
bool content_contains(address addr) const { return content_begin() <= addr && addr < content_end(); }
|
||||||
bool data_contains(address addr) const { return data_begin() <= addr && addr < data_end(); }
|
bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); }
|
||||||
bool contains(address addr) const { return instructions_contains(addr); }
|
bool data_contains(address addr) const { return data_begin() <= addr && addr < data_end(); }
|
||||||
bool is_frame_complete_at(address addr) const { return instructions_contains(addr) &&
|
bool contains(address addr) const { return content_contains(addr); }
|
||||||
addr >= instructions_begin() + _frame_complete_offset; }
|
bool is_frame_complete_at(address addr) const { return code_contains(addr) &&
|
||||||
|
addr >= code_begin() + _frame_complete_offset; }
|
||||||
|
|
||||||
// CodeCache support: really only used by the nmethods, but in order to get
|
// CodeCache support: really only used by the nmethods, but in order to get
|
||||||
// asserts and certain bookkeeping to work in the CodeCache they are defined
|
// asserts and certain bookkeeping to work in the CodeCache they are defined
|
||||||
@ -169,7 +176,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||||||
|
|
||||||
// Print the comment associated with offset on stream, if there is one
|
// Print the comment associated with offset on stream, if there is one
|
||||||
virtual void print_block_comment(outputStream* stream, address block_begin) {
|
virtual void print_block_comment(outputStream* stream, address block_begin) {
|
||||||
intptr_t offset = (intptr_t)(block_begin - instructions_begin());
|
intptr_t offset = (intptr_t)(block_begin - code_begin());
|
||||||
_comments.print_block_comment(stream, offset);
|
_comments.print_block_comment(stream, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +293,7 @@ class RuntimeStub: public CodeBlob {
|
|||||||
// GC support
|
// GC support
|
||||||
bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
|
bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
|
||||||
|
|
||||||
address entry_point() { return instructions_begin(); }
|
address entry_point() { return code_begin(); }
|
||||||
|
|
||||||
// GC/Verification support
|
// GC/Verification support
|
||||||
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }
|
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }
|
||||||
@ -313,13 +320,15 @@ class SingletonBlob: public CodeBlob {
|
|||||||
OopMapSet* oop_maps
|
OopMapSet* oop_maps
|
||||||
)
|
)
|
||||||
: CodeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
|
: CodeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
bool is_alive() const { return true; }
|
address entry_point() { return code_begin(); }
|
||||||
|
|
||||||
void verify(); // does nothing
|
bool is_alive() const { return true; }
|
||||||
void print_on(outputStream* st) const;
|
|
||||||
void print_value_on(outputStream* st) const;
|
void verify(); // does nothing
|
||||||
|
void print_on(outputStream* st) const;
|
||||||
|
void print_value_on(outputStream* st) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -376,9 +385,9 @@ class DeoptimizationBlob: public SingletonBlob {
|
|||||||
// Printing
|
// Printing
|
||||||
void print_value_on(outputStream* st) const;
|
void print_value_on(outputStream* st) const;
|
||||||
|
|
||||||
address unpack() const { return instructions_begin() + _unpack_offset; }
|
address unpack() const { return code_begin() + _unpack_offset; }
|
||||||
address unpack_with_exception() const { return instructions_begin() + _unpack_with_exception; }
|
address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }
|
||||||
address unpack_with_reexecution() const { return instructions_begin() + _unpack_with_reexecution; }
|
address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }
|
||||||
|
|
||||||
// Alternate entry point for C1 where the exception and issuing pc
|
// Alternate entry point for C1 where the exception and issuing pc
|
||||||
// are in JavaThread::_exception_oop and JavaThread::_exception_pc
|
// are in JavaThread::_exception_oop and JavaThread::_exception_pc
|
||||||
@ -387,9 +396,9 @@ class DeoptimizationBlob: public SingletonBlob {
|
|||||||
// there may be live values in those registers during deopt.
|
// there may be live values in those registers during deopt.
|
||||||
void set_unpack_with_exception_in_tls_offset(int offset) {
|
void set_unpack_with_exception_in_tls_offset(int offset) {
|
||||||
_unpack_with_exception_in_tls = offset;
|
_unpack_with_exception_in_tls = offset;
|
||||||
assert(contains(instructions_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
|
assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
|
||||||
}
|
}
|
||||||
address unpack_with_exception_in_tls() const { return instructions_begin() + _unpack_with_exception_in_tls; }
|
address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,14 +76,14 @@ class CodeBlob_sizes {
|
|||||||
relocation_size += cb->relocation_size();
|
relocation_size += cb->relocation_size();
|
||||||
if (cb->is_nmethod()) {
|
if (cb->is_nmethod()) {
|
||||||
nmethod* nm = cb->as_nmethod_or_null();
|
nmethod* nm = cb->as_nmethod_or_null();
|
||||||
code_size += nm->code_size();
|
code_size += nm->insts_size();
|
||||||
stub_size += nm->stub_size();
|
stub_size += nm->stub_size();
|
||||||
|
|
||||||
scopes_oop_size += nm->oops_size();
|
scopes_oop_size += nm->oops_size();
|
||||||
scopes_data_size += nm->scopes_data_size();
|
scopes_data_size += nm->scopes_data_size();
|
||||||
scopes_pcs_size += nm->scopes_pcs_size();
|
scopes_pcs_size += nm->scopes_pcs_size();
|
||||||
} else {
|
} else {
|
||||||
code_size += cb->instructions_size();
|
code_size += cb->code_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -210,7 +210,7 @@ void CodeCache::commit(CodeBlob* cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// flush the hardware I-cache
|
// flush the hardware I-cache
|
||||||
ICache::invalidate_range(cb->instructions_begin(), cb->instructions_size());
|
ICache::invalidate_range(cb->content_begin(), cb->content_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -804,8 +804,8 @@ void CodeCache::print_internals() {
|
|||||||
|
|
||||||
if(nm->method() != NULL && nm->is_java_method()) {
|
if(nm->method() != NULL && nm->is_java_method()) {
|
||||||
nmethodJava++;
|
nmethodJava++;
|
||||||
if(nm->code_size() > maxCodeSize) {
|
if (nm->insts_size() > maxCodeSize) {
|
||||||
maxCodeSize = nm->code_size();
|
maxCodeSize = nm->insts_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cb->is_runtime_stub()) {
|
} else if (cb->is_runtime_stub()) {
|
||||||
@ -830,7 +830,7 @@ void CodeCache::print_internals() {
|
|||||||
if (cb->is_nmethod()) {
|
if (cb->is_nmethod()) {
|
||||||
nmethod* nm = (nmethod*)cb;
|
nmethod* nm = (nmethod*)cb;
|
||||||
if(nm->is_java_method()) {
|
if(nm->is_java_method()) {
|
||||||
buckets[nm->code_size() / bucketSize]++;
|
buckets[nm->insts_size() / bucketSize]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -896,11 +896,11 @@ void CodeCache::print() {
|
|||||||
FOR_ALL_BLOBS(p) {
|
FOR_ALL_BLOBS(p) {
|
||||||
if (p->is_alive()) {
|
if (p->is_alive()) {
|
||||||
number_of_blobs++;
|
number_of_blobs++;
|
||||||
code_size += p->instructions_size();
|
code_size += p->code_size();
|
||||||
OopMapSet* set = p->oop_maps();
|
OopMapSet* set = p->oop_maps();
|
||||||
if (set != NULL) {
|
if (set != NULL) {
|
||||||
number_of_oop_maps += set->size();
|
number_of_oop_maps += set->size();
|
||||||
map_size += set->heap_size();
|
map_size += set->heap_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -219,8 +219,8 @@ void ImplicitExceptionTable::copy_to( nmethod* nm ) {
|
|||||||
|
|
||||||
void ImplicitExceptionTable::verify(nmethod *nm) const {
|
void ImplicitExceptionTable::verify(nmethod *nm) const {
|
||||||
for (uint i = 0; i < len(); i++) {
|
for (uint i = 0; i < len(); i++) {
|
||||||
if ((*adr(i) > (unsigned int)nm->code_size()) ||
|
if ((*adr(i) > (unsigned int)nm->insts_size()) ||
|
||||||
(*(adr(i)+1) > (unsigned int)nm->code_size()))
|
(*(adr(i)+1) > (unsigned int)nm->insts_size()))
|
||||||
fatal(err_msg("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, _data));
|
fatal(err_msg("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, _data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,9 +87,9 @@ struct nmethod_stats_struct {
|
|||||||
int nmethod_count;
|
int nmethod_count;
|
||||||
int total_size;
|
int total_size;
|
||||||
int relocation_size;
|
int relocation_size;
|
||||||
int code_size;
|
|
||||||
int stub_size;
|
|
||||||
int consts_size;
|
int consts_size;
|
||||||
|
int insts_size;
|
||||||
|
int stub_size;
|
||||||
int scopes_data_size;
|
int scopes_data_size;
|
||||||
int scopes_pcs_size;
|
int scopes_pcs_size;
|
||||||
int dependencies_size;
|
int dependencies_size;
|
||||||
@ -101,9 +101,9 @@ struct nmethod_stats_struct {
|
|||||||
nmethod_count += 1;
|
nmethod_count += 1;
|
||||||
total_size += nm->size();
|
total_size += nm->size();
|
||||||
relocation_size += nm->relocation_size();
|
relocation_size += nm->relocation_size();
|
||||||
code_size += nm->code_size();
|
|
||||||
stub_size += nm->stub_size();
|
|
||||||
consts_size += nm->consts_size();
|
consts_size += nm->consts_size();
|
||||||
|
insts_size += nm->insts_size();
|
||||||
|
stub_size += nm->stub_size();
|
||||||
oops_size += nm->oops_size();
|
oops_size += nm->oops_size();
|
||||||
scopes_data_size += nm->scopes_data_size();
|
scopes_data_size += nm->scopes_data_size();
|
||||||
scopes_pcs_size += nm->scopes_pcs_size();
|
scopes_pcs_size += nm->scopes_pcs_size();
|
||||||
@ -116,9 +116,9 @@ struct nmethod_stats_struct {
|
|||||||
tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count);
|
tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count);
|
||||||
if (total_size != 0) tty->print_cr(" total in heap = %d", total_size);
|
if (total_size != 0) tty->print_cr(" total in heap = %d", total_size);
|
||||||
if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size);
|
if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size);
|
||||||
if (code_size != 0) tty->print_cr(" main code = %d", code_size);
|
|
||||||
if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size);
|
|
||||||
if (consts_size != 0) tty->print_cr(" constants = %d", consts_size);
|
if (consts_size != 0) tty->print_cr(" constants = %d", consts_size);
|
||||||
|
if (insts_size != 0) tty->print_cr(" main code = %d", insts_size);
|
||||||
|
if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size);
|
||||||
if (oops_size != 0) tty->print_cr(" oops = %d", oops_size);
|
if (oops_size != 0) tty->print_cr(" oops = %d", oops_size);
|
||||||
if (scopes_data_size != 0) tty->print_cr(" scopes data = %d", scopes_data_size);
|
if (scopes_data_size != 0) tty->print_cr(" scopes data = %d", scopes_data_size);
|
||||||
if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size);
|
if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size);
|
||||||
@ -130,13 +130,13 @@ struct nmethod_stats_struct {
|
|||||||
int native_nmethod_count;
|
int native_nmethod_count;
|
||||||
int native_total_size;
|
int native_total_size;
|
||||||
int native_relocation_size;
|
int native_relocation_size;
|
||||||
int native_code_size;
|
int native_insts_size;
|
||||||
int native_oops_size;
|
int native_oops_size;
|
||||||
void note_native_nmethod(nmethod* nm) {
|
void note_native_nmethod(nmethod* nm) {
|
||||||
native_nmethod_count += 1;
|
native_nmethod_count += 1;
|
||||||
native_total_size += nm->size();
|
native_total_size += nm->size();
|
||||||
native_relocation_size += nm->relocation_size();
|
native_relocation_size += nm->relocation_size();
|
||||||
native_code_size += nm->code_size();
|
native_insts_size += nm->insts_size();
|
||||||
native_oops_size += nm->oops_size();
|
native_oops_size += nm->oops_size();
|
||||||
}
|
}
|
||||||
void print_native_nmethod_stats() {
|
void print_native_nmethod_stats() {
|
||||||
@ -144,7 +144,7 @@ struct nmethod_stats_struct {
|
|||||||
tty->print_cr("Statistics for %d native nmethods:", native_nmethod_count);
|
tty->print_cr("Statistics for %d native nmethods:", native_nmethod_count);
|
||||||
if (native_total_size != 0) tty->print_cr(" N. total size = %d", native_total_size);
|
if (native_total_size != 0) tty->print_cr(" N. total size = %d", native_total_size);
|
||||||
if (native_relocation_size != 0) tty->print_cr(" N. relocation = %d", native_relocation_size);
|
if (native_relocation_size != 0) tty->print_cr(" N. relocation = %d", native_relocation_size);
|
||||||
if (native_code_size != 0) tty->print_cr(" N. main code = %d", native_code_size);
|
if (native_insts_size != 0) tty->print_cr(" N. main code = %d", native_insts_size);
|
||||||
if (native_oops_size != 0) tty->print_cr(" N. oops = %d", native_oops_size);
|
if (native_oops_size != 0) tty->print_cr(" N. oops = %d", native_oops_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,9 +404,9 @@ void nmethod::add_handler_for_exception_and_pc(Handle exception, address pc, add
|
|||||||
|
|
||||||
int nmethod::total_size() const {
|
int nmethod::total_size() const {
|
||||||
return
|
return
|
||||||
code_size() +
|
|
||||||
stub_size() +
|
|
||||||
consts_size() +
|
consts_size() +
|
||||||
|
insts_size() +
|
||||||
|
stub_size() +
|
||||||
scopes_data_size() +
|
scopes_data_size() +
|
||||||
scopes_pcs_size() +
|
scopes_pcs_size() +
|
||||||
handler_table_size() +
|
handler_table_size() +
|
||||||
@ -618,8 +618,8 @@ nmethod::nmethod(
|
|||||||
_deoptimize_mh_offset = 0;
|
_deoptimize_mh_offset = 0;
|
||||||
_orig_pc_offset = 0;
|
_orig_pc_offset = 0;
|
||||||
|
|
||||||
_stub_offset = data_offset();
|
|
||||||
_consts_offset = data_offset();
|
_consts_offset = data_offset();
|
||||||
|
_stub_offset = data_offset();
|
||||||
_oops_offset = data_offset();
|
_oops_offset = data_offset();
|
||||||
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
|
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
|
||||||
_scopes_pcs_offset = _scopes_data_offset;
|
_scopes_pcs_offset = _scopes_data_offset;
|
||||||
@ -629,8 +629,8 @@ nmethod::nmethod(
|
|||||||
_nmethod_end_offset = _nul_chk_table_offset;
|
_nmethod_end_offset = _nul_chk_table_offset;
|
||||||
_compile_id = 0; // default
|
_compile_id = 0; // default
|
||||||
_comp_level = CompLevel_none;
|
_comp_level = CompLevel_none;
|
||||||
_entry_point = instructions_begin();
|
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
|
||||||
_verified_entry_point = instructions_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
||||||
_osr_entry_point = NULL;
|
_osr_entry_point = NULL;
|
||||||
_exception_cache = NULL;
|
_exception_cache = NULL;
|
||||||
_pc_desc_cache.reset_to(NULL);
|
_pc_desc_cache.reset_to(NULL);
|
||||||
@ -696,8 +696,8 @@ nmethod::nmethod(
|
|||||||
_unwind_handler_offset = -1;
|
_unwind_handler_offset = -1;
|
||||||
_trap_offset = offsets->value(CodeOffsets::Dtrace_trap);
|
_trap_offset = offsets->value(CodeOffsets::Dtrace_trap);
|
||||||
_orig_pc_offset = 0;
|
_orig_pc_offset = 0;
|
||||||
_stub_offset = data_offset();
|
|
||||||
_consts_offset = data_offset();
|
_consts_offset = data_offset();
|
||||||
|
_stub_offset = data_offset();
|
||||||
_oops_offset = data_offset();
|
_oops_offset = data_offset();
|
||||||
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
|
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
|
||||||
_scopes_pcs_offset = _scopes_data_offset;
|
_scopes_pcs_offset = _scopes_data_offset;
|
||||||
@ -707,8 +707,8 @@ nmethod::nmethod(
|
|||||||
_nmethod_end_offset = _nul_chk_table_offset;
|
_nmethod_end_offset = _nul_chk_table_offset;
|
||||||
_compile_id = 0; // default
|
_compile_id = 0; // default
|
||||||
_comp_level = CompLevel_none;
|
_comp_level = CompLevel_none;
|
||||||
_entry_point = instructions_begin();
|
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
|
||||||
_verified_entry_point = instructions_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
||||||
_osr_entry_point = NULL;
|
_osr_entry_point = NULL;
|
||||||
_exception_cache = NULL;
|
_exception_cache = NULL;
|
||||||
_pc_desc_cache.reset_to(NULL);
|
_pc_desc_cache.reset_to(NULL);
|
||||||
@ -787,18 +787,25 @@ nmethod::nmethod(
|
|||||||
_comp_level = comp_level;
|
_comp_level = comp_level;
|
||||||
_compiler = compiler;
|
_compiler = compiler;
|
||||||
_orig_pc_offset = orig_pc_offset;
|
_orig_pc_offset = orig_pc_offset;
|
||||||
_stub_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start());
|
|
||||||
|
// Section offsets
|
||||||
|
_consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts());
|
||||||
|
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
|
||||||
|
|
||||||
// Exception handler and deopt handler are in the stub section
|
// Exception handler and deopt handler are in the stub section
|
||||||
_exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions);
|
_exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions);
|
||||||
_deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt);
|
_deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt);
|
||||||
_deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH);
|
if (has_method_handle_invokes()) {
|
||||||
if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
|
_deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH);
|
||||||
_unwind_handler_offset = instructions_offset() + offsets->value(CodeOffsets::UnwindHandler);
|
|
||||||
} else {
|
} else {
|
||||||
_unwind_handler_offset = -1;
|
_deoptimize_mh_offset = -1;
|
||||||
}
|
}
|
||||||
_consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
|
if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
|
||||||
|
_unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler);
|
||||||
|
} else {
|
||||||
|
_unwind_handler_offset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
_oops_offset = data_offset();
|
_oops_offset = data_offset();
|
||||||
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size (), oopSize);
|
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size (), oopSize);
|
||||||
_scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
|
_scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
|
||||||
@ -807,9 +814,9 @@ nmethod::nmethod(
|
|||||||
_nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
|
_nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
|
||||||
_nmethod_end_offset = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
|
_nmethod_end_offset = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
|
||||||
|
|
||||||
_entry_point = instructions_begin();
|
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
|
||||||
_verified_entry_point = instructions_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
||||||
_osr_entry_point = instructions_begin() + offsets->value(CodeOffsets::OSR_Entry);
|
_osr_entry_point = code_begin() + offsets->value(CodeOffsets::OSR_Entry);
|
||||||
_exception_cache = NULL;
|
_exception_cache = NULL;
|
||||||
_pc_desc_cache.reset_to(scopes_pcs_begin());
|
_pc_desc_cache.reset_to(scopes_pcs_begin());
|
||||||
|
|
||||||
@ -878,14 +885,13 @@ void nmethod::log_new_nmethod() const {
|
|||||||
HandleMark hm;
|
HandleMark hm;
|
||||||
xtty->begin_elem("nmethod");
|
xtty->begin_elem("nmethod");
|
||||||
log_identity(xtty);
|
log_identity(xtty);
|
||||||
xtty->print(" entry='" INTPTR_FORMAT "' size='%d'",
|
xtty->print(" entry='" INTPTR_FORMAT "' size='%d'", code_begin(), size());
|
||||||
instructions_begin(), size());
|
|
||||||
xtty->print(" address='" INTPTR_FORMAT "'", (intptr_t) this);
|
xtty->print(" address='" INTPTR_FORMAT "'", (intptr_t) this);
|
||||||
|
|
||||||
LOG_OFFSET(xtty, relocation);
|
LOG_OFFSET(xtty, relocation);
|
||||||
LOG_OFFSET(xtty, code);
|
|
||||||
LOG_OFFSET(xtty, stub);
|
|
||||||
LOG_OFFSET(xtty, consts);
|
LOG_OFFSET(xtty, consts);
|
||||||
|
LOG_OFFSET(xtty, insts);
|
||||||
|
LOG_OFFSET(xtty, stub);
|
||||||
LOG_OFFSET(xtty, scopes_data);
|
LOG_OFFSET(xtty, scopes_data);
|
||||||
LOG_OFFSET(xtty, scopes_pcs);
|
LOG_OFFSET(xtty, scopes_pcs);
|
||||||
LOG_OFFSET(xtty, dependencies);
|
LOG_OFFSET(xtty, dependencies);
|
||||||
@ -1460,7 +1466,7 @@ void nmethod::post_compiled_method_load_event() {
|
|||||||
moop->name()->utf8_length(),
|
moop->name()->utf8_length(),
|
||||||
moop->signature()->bytes(),
|
moop->signature()->bytes(),
|
||||||
moop->signature()->utf8_length(),
|
moop->signature()->utf8_length(),
|
||||||
code_begin(), code_size());
|
insts_begin(), insts_size());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_compiled_method_load() ||
|
if (JvmtiExport::should_post_compiled_method_load() ||
|
||||||
JvmtiExport::should_post_compiled_method_unload()) {
|
JvmtiExport::should_post_compiled_method_unload()) {
|
||||||
@ -1502,7 +1508,7 @@ void nmethod::post_compiled_method_unload() {
|
|||||||
if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
|
if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
|
||||||
assert(!unload_reported(), "already unloaded");
|
assert(!unload_reported(), "already unloaded");
|
||||||
HandleMark hm;
|
HandleMark hm;
|
||||||
JvmtiExport::post_compiled_method_unload(_jmethod_id, code_begin());
|
JvmtiExport::post_compiled_method_unload(_jmethod_id, insts_begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The JVMTI CompiledMethodUnload event can be enabled or disabled at
|
// The JVMTI CompiledMethodUnload event can be enabled or disabled at
|
||||||
@ -1854,7 +1860,7 @@ void nmethod::copy_scopes_pcs(PcDesc* pcs, int count) {
|
|||||||
// Adjust the final sentinel downward.
|
// Adjust the final sentinel downward.
|
||||||
PcDesc* last_pc = &scopes_pcs_begin()[count-1];
|
PcDesc* last_pc = &scopes_pcs_begin()[count-1];
|
||||||
assert(last_pc->pc_offset() == PcDesc::upper_offset_limit, "sanity");
|
assert(last_pc->pc_offset() == PcDesc::upper_offset_limit, "sanity");
|
||||||
last_pc->set_pc_offset(instructions_size() + 1);
|
last_pc->set_pc_offset(content_size() + 1);
|
||||||
for (; last_pc + 1 < scopes_pcs_end(); last_pc += 1) {
|
for (; last_pc + 1 < scopes_pcs_end(); last_pc += 1) {
|
||||||
// Fill any rounding gaps with copies of the last record.
|
// Fill any rounding gaps with copies of the last record.
|
||||||
last_pc[1] = last_pc[0];
|
last_pc[1] = last_pc[0];
|
||||||
@ -1894,7 +1900,7 @@ static PcDesc* linear_search(nmethod* nm, int pc_offset, bool approximate) {
|
|||||||
|
|
||||||
// Finds a PcDesc with real-pc equal to "pc"
|
// Finds a PcDesc with real-pc equal to "pc"
|
||||||
PcDesc* nmethod::find_pc_desc_internal(address pc, bool approximate) {
|
PcDesc* nmethod::find_pc_desc_internal(address pc, bool approximate) {
|
||||||
address base_address = instructions_begin();
|
address base_address = code_begin();
|
||||||
if ((pc < base_address) ||
|
if ((pc < base_address) ||
|
||||||
(pc - base_address) >= (ptrdiff_t) PcDesc::upper_offset_limit) {
|
(pc - base_address) >= (ptrdiff_t) PcDesc::upper_offset_limit) {
|
||||||
return NULL; // PC is wildly out of range
|
return NULL; // PC is wildly out of range
|
||||||
@ -2042,7 +2048,7 @@ bool nmethod::is_dependent_on_method(methodOop dependee) {
|
|||||||
|
|
||||||
|
|
||||||
bool nmethod::is_patchable_at(address instr_addr) {
|
bool nmethod::is_patchable_at(address instr_addr) {
|
||||||
assert (code_contains(instr_addr), "wrong nmethod used");
|
assert(insts_contains(instr_addr), "wrong nmethod used");
|
||||||
if (is_zombie()) {
|
if (is_zombie()) {
|
||||||
// a zombie may never be patched
|
// a zombie may never be patched
|
||||||
return false;
|
return false;
|
||||||
@ -2054,7 +2060,7 @@ bool nmethod::is_patchable_at(address instr_addr) {
|
|||||||
address nmethod::continuation_for_implicit_exception(address pc) {
|
address nmethod::continuation_for_implicit_exception(address pc) {
|
||||||
// Exception happened outside inline-cache check code => we are inside
|
// Exception happened outside inline-cache check code => we are inside
|
||||||
// an active nmethod => use cpc to determine a return address
|
// an active nmethod => use cpc to determine a return address
|
||||||
int exception_offset = pc - instructions_begin();
|
int exception_offset = pc - code_begin();
|
||||||
int cont_offset = ImplicitExceptionTable(this).at( exception_offset );
|
int cont_offset = ImplicitExceptionTable(this).at( exception_offset );
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (cont_offset == 0) {
|
if (cont_offset == 0) {
|
||||||
@ -2075,7 +2081,7 @@ address nmethod::continuation_for_implicit_exception(address pc) {
|
|||||||
// Let the normal error handling report the exception
|
// Let the normal error handling report the exception
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return instructions_begin() + cont_offset;
|
return code_begin() + cont_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2334,18 +2340,18 @@ void nmethod::print() const {
|
|||||||
relocation_begin(),
|
relocation_begin(),
|
||||||
relocation_end(),
|
relocation_end(),
|
||||||
relocation_size());
|
relocation_size());
|
||||||
if (code_size () > 0) tty->print_cr(" main code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
|
||||||
code_begin(),
|
|
||||||
code_end(),
|
|
||||||
code_size());
|
|
||||||
if (stub_size () > 0) tty->print_cr(" stub code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
|
||||||
stub_begin(),
|
|
||||||
stub_end(),
|
|
||||||
stub_size());
|
|
||||||
if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
||||||
consts_begin(),
|
consts_begin(),
|
||||||
consts_end(),
|
consts_end(),
|
||||||
consts_size());
|
consts_size());
|
||||||
|
if (insts_size () > 0) tty->print_cr(" main code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
||||||
|
insts_begin(),
|
||||||
|
insts_end(),
|
||||||
|
insts_size());
|
||||||
|
if (stub_size () > 0) tty->print_cr(" stub code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
||||||
|
stub_begin(),
|
||||||
|
stub_end(),
|
||||||
|
stub_size());
|
||||||
if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
||||||
oops_begin(),
|
oops_begin(),
|
||||||
oops_end(),
|
oops_end(),
|
||||||
@ -2370,10 +2376,6 @@ void nmethod::print() const {
|
|||||||
nul_chk_table_begin(),
|
nul_chk_table_begin(),
|
||||||
nul_chk_table_end(),
|
nul_chk_table_end(),
|
||||||
nul_chk_table_size());
|
nul_chk_table_size());
|
||||||
if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
|
|
||||||
oops_begin(),
|
|
||||||
oops_end(),
|
|
||||||
oops_size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::print_code() {
|
void nmethod::print_code() {
|
||||||
@ -2607,7 +2609,7 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
|
|||||||
// First, find an oopmap in (begin, end].
|
// First, find an oopmap in (begin, end].
|
||||||
// We use the odd half-closed interval so that oop maps and scope descs
|
// We use the odd half-closed interval so that oop maps and scope descs
|
||||||
// which are tied to the byte after a call are printed with the call itself.
|
// which are tied to the byte after a call are printed with the call itself.
|
||||||
address base = instructions_begin();
|
address base = code_begin();
|
||||||
OopMapSet* oms = oop_maps();
|
OopMapSet* oms = oop_maps();
|
||||||
if (oms != NULL) {
|
if (oms != NULL) {
|
||||||
for (int i = 0, imax = oms->size(); i < imax; i++) {
|
for (int i = 0, imax = oms->size(); i < imax; i++) {
|
||||||
@ -2695,10 +2697,10 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
|
|||||||
st->move_to(column);
|
st->move_to(column);
|
||||||
st->print("; {%s}", str);
|
st->print("; {%s}", str);
|
||||||
}
|
}
|
||||||
int cont_offset = ImplicitExceptionTable(this).at(begin - instructions_begin());
|
int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
|
||||||
if (cont_offset != 0) {
|
if (cont_offset != 0) {
|
||||||
st->move_to(column);
|
st->move_to(column);
|
||||||
st->print("; implicit exception: dispatches to " INTPTR_FORMAT, instructions_begin() + cont_offset);
|
st->print("; implicit exception: dispatches to " INTPTR_FORMAT, code_begin() + cont_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2732,7 +2734,7 @@ void nmethod::print_handler_table() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::print_nul_chk_table() {
|
void nmethod::print_nul_chk_table() {
|
||||||
ImplicitExceptionTable(this).print(instructions_begin());
|
ImplicitExceptionTable(this).print(code_begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::print_statistics() {
|
void nmethod::print_statistics() {
|
||||||
|
@ -143,8 +143,8 @@ class nmethod : public CodeBlob {
|
|||||||
#ifdef HAVE_DTRACE_H
|
#ifdef HAVE_DTRACE_H
|
||||||
int _trap_offset;
|
int _trap_offset;
|
||||||
#endif // def HAVE_DTRACE_H
|
#endif // def HAVE_DTRACE_H
|
||||||
int _stub_offset;
|
|
||||||
int _consts_offset;
|
int _consts_offset;
|
||||||
|
int _stub_offset;
|
||||||
int _oops_offset; // offset to where embedded oop table begins (inside data)
|
int _oops_offset; // offset to where embedded oop table begins (inside data)
|
||||||
int _scopes_data_offset;
|
int _scopes_data_offset;
|
||||||
int _scopes_pcs_offset;
|
int _scopes_pcs_offset;
|
||||||
@ -312,7 +312,7 @@ class nmethod : public CodeBlob {
|
|||||||
int frame_size);
|
int frame_size);
|
||||||
|
|
||||||
int trap_offset() const { return _trap_offset; }
|
int trap_offset() const { return _trap_offset; }
|
||||||
address trap_address() const { return code_begin() + _trap_offset; }
|
address trap_address() const { return insts_begin() + _trap_offset; }
|
||||||
|
|
||||||
#endif // def HAVE_DTRACE_H
|
#endif // def HAVE_DTRACE_H
|
||||||
|
|
||||||
@ -336,16 +336,16 @@ class nmethod : public CodeBlob {
|
|||||||
bool is_compiled_by_shark() const;
|
bool is_compiled_by_shark() const;
|
||||||
|
|
||||||
// boundaries for different parts
|
// boundaries for different parts
|
||||||
address code_begin () const { return _entry_point; }
|
address consts_begin () const { return header_begin() + _consts_offset ; }
|
||||||
address code_end () const { return header_begin() + _stub_offset ; }
|
address consts_end () const { return header_begin() + code_offset() ; }
|
||||||
|
address insts_begin () const { return header_begin() + code_offset() ; }
|
||||||
|
address insts_end () const { return header_begin() + _stub_offset ; }
|
||||||
|
address stub_begin () const { return header_begin() + _stub_offset ; }
|
||||||
|
address stub_end () const { return header_begin() + _oops_offset ; }
|
||||||
address exception_begin () const { return header_begin() + _exception_offset ; }
|
address exception_begin () const { return header_begin() + _exception_offset ; }
|
||||||
address deopt_handler_begin () const { return header_begin() + _deoptimize_offset ; }
|
address deopt_handler_begin () const { return header_begin() + _deoptimize_offset ; }
|
||||||
address deopt_mh_handler_begin() const { return header_begin() + _deoptimize_mh_offset ; }
|
address deopt_mh_handler_begin() const { return header_begin() + _deoptimize_mh_offset ; }
|
||||||
address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
|
address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
|
||||||
address stub_begin () const { return header_begin() + _stub_offset ; }
|
|
||||||
address stub_end () const { return header_begin() + _consts_offset ; }
|
|
||||||
address consts_begin () const { return header_begin() + _consts_offset ; }
|
|
||||||
address consts_end () const { return header_begin() + _oops_offset ; }
|
|
||||||
oop* oops_begin () const { return (oop*) (header_begin() + _oops_offset) ; }
|
oop* oops_begin () const { return (oop*) (header_begin() + _oops_offset) ; }
|
||||||
oop* oops_end () const { return (oop*) (header_begin() + _scopes_data_offset) ; }
|
oop* oops_end () const { return (oop*) (header_begin() + _scopes_data_offset) ; }
|
||||||
|
|
||||||
@ -361,9 +361,9 @@ class nmethod : public CodeBlob {
|
|||||||
address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; }
|
address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; }
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
int code_size () const { return code_end () - code_begin (); }
|
|
||||||
int stub_size () const { return stub_end () - stub_begin (); }
|
|
||||||
int consts_size () const { return consts_end () - consts_begin (); }
|
int consts_size () const { return consts_end () - consts_begin (); }
|
||||||
|
int insts_size () const { return insts_end () - insts_begin (); }
|
||||||
|
int stub_size () const { return stub_end () - stub_begin (); }
|
||||||
int oops_size () const { return (address) oops_end () - (address) oops_begin (); }
|
int oops_size () const { return (address) oops_end () - (address) oops_begin (); }
|
||||||
int scopes_data_size () const { return scopes_data_end () - scopes_data_begin (); }
|
int scopes_data_size () const { return scopes_data_end () - scopes_data_begin (); }
|
||||||
int scopes_pcs_size () const { return (intptr_t) scopes_pcs_end () - (intptr_t) scopes_pcs_begin (); }
|
int scopes_pcs_size () const { return (intptr_t) scopes_pcs_end () - (intptr_t) scopes_pcs_begin (); }
|
||||||
@ -374,9 +374,9 @@ class nmethod : public CodeBlob {
|
|||||||
int total_size () const;
|
int total_size () const;
|
||||||
|
|
||||||
// Containment
|
// Containment
|
||||||
bool code_contains (address addr) const { return code_begin () <= addr && addr < code_end (); }
|
|
||||||
bool stub_contains (address addr) const { return stub_begin () <= addr && addr < stub_end (); }
|
|
||||||
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
|
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
|
||||||
|
bool insts_contains (address addr) const { return insts_begin () <= addr && addr < insts_end (); }
|
||||||
|
bool stub_contains (address addr) const { return stub_begin () <= addr && addr < stub_end (); }
|
||||||
bool oops_contains (oop* addr) const { return oops_begin () <= addr && addr < oops_end (); }
|
bool oops_contains (oop* addr) const { return oops_begin () <= addr && addr < oops_end (); }
|
||||||
bool scopes_data_contains (address addr) const { return scopes_data_begin () <= addr && addr < scopes_data_end (); }
|
bool scopes_data_contains (address addr) const { return scopes_data_begin () <= addr && addr < scopes_data_end (); }
|
||||||
bool scopes_pcs_contains (PcDesc* addr) const { return scopes_pcs_begin () <= addr && addr < scopes_pcs_end (); }
|
bool scopes_pcs_contains (PcDesc* addr) const { return scopes_pcs_begin () <= addr && addr < scopes_pcs_end (); }
|
||||||
@ -506,7 +506,7 @@ public:
|
|||||||
void clear_inline_caches();
|
void clear_inline_caches();
|
||||||
void cleanup_inline_caches();
|
void cleanup_inline_caches();
|
||||||
bool inlinecache_check_contains(address addr) const {
|
bool inlinecache_check_contains(address addr) const {
|
||||||
return (addr >= instructions_begin() && addr < verified_entry_point());
|
return (addr >= code_begin() && addr < verified_entry_point());
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlink and deallocate this nmethod
|
// unlink and deallocate this nmethod
|
||||||
@ -559,7 +559,7 @@ public:
|
|||||||
|
|
||||||
PcDesc* find_pc_desc(address pc, bool approximate) {
|
PcDesc* find_pc_desc(address pc, bool approximate) {
|
||||||
PcDesc* desc = _pc_desc_cache.last_pc_desc();
|
PcDesc* desc = _pc_desc_cache.last_pc_desc();
|
||||||
if (desc != NULL && desc->pc_offset() == pc - instructions_begin()) {
|
if (desc != NULL && desc->pc_offset() == pc - code_begin()) {
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
return find_pc_desc_internal(pc, approximate);
|
return find_pc_desc_internal(pc, approximate);
|
||||||
|
@ -34,7 +34,7 @@ PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
address PcDesc::real_pc(const nmethod* code) const {
|
address PcDesc::real_pc(const nmethod* code) const {
|
||||||
return code->instructions_begin() + pc_offset();
|
return code->code_begin() + pc_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcDesc::print(nmethod* code) {
|
void PcDesc::print(nmethod* code) {
|
||||||
|
@ -128,13 +128,20 @@ void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
|
|||||||
_code = nm;
|
_code = nm;
|
||||||
_current = nm->relocation_begin() - 1;
|
_current = nm->relocation_begin() - 1;
|
||||||
_end = nm->relocation_end();
|
_end = nm->relocation_end();
|
||||||
_addr = (address) nm->instructions_begin();
|
_addr = nm->content_begin();
|
||||||
|
|
||||||
|
// Initialize code sections.
|
||||||
|
_section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin();
|
||||||
|
_section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ;
|
||||||
|
_section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ;
|
||||||
|
|
||||||
|
_section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ;
|
||||||
|
_section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ;
|
||||||
|
_section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ;
|
||||||
|
|
||||||
assert(!has_current(), "just checking");
|
assert(!has_current(), "just checking");
|
||||||
address code_end = nm->instructions_end();
|
assert(begin == NULL || begin >= nm->code_begin(), "in bounds");
|
||||||
|
assert(limit == NULL || limit <= nm->code_end(), "in bounds");
|
||||||
assert(begin == NULL || begin >= nm->instructions_begin(), "in bounds");
|
|
||||||
// FIX THIS assert(limit == NULL || limit <= code_end, "in bounds");
|
|
||||||
set_limits(begin, limit);
|
set_limits(begin, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,9 +155,11 @@ RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
|
|||||||
_code = NULL; // Not cb->blob();
|
_code = NULL; // Not cb->blob();
|
||||||
|
|
||||||
CodeBuffer* cb = cs->outer();
|
CodeBuffer* cb = cs->outer();
|
||||||
assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
|
assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
|
||||||
for (int n = 0; n < (int)SECT_LIMIT; n++) {
|
for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
|
||||||
_section_start[n] = cb->code_section(n)->start();
|
CodeSection* cs = cb->code_section(n);
|
||||||
|
_section_start[n] = cs->start();
|
||||||
|
_section_end [n] = cs->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!has_current(), "just checking");
|
assert(!has_current(), "just checking");
|
||||||
@ -168,6 +177,12 @@ struct RelocIndexEntry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool RelocIterator::addr_in_const() const {
|
||||||
|
const int n = CodeBuffer::SECT_CONSTS;
|
||||||
|
return section_start(n) <= addr() && addr() < section_end(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int num_cards(int code_size) {
|
static inline int num_cards(int code_size) {
|
||||||
return (code_size-1) / indexCardSize;
|
return (code_size-1) / indexCardSize;
|
||||||
}
|
}
|
||||||
@ -267,7 +282,7 @@ void RelocIterator::set_limits(address begin, address limit) {
|
|||||||
// skip ahead
|
// skip ahead
|
||||||
RelocIndexEntry* index = (RelocIndexEntry*)_end;
|
RelocIndexEntry* index = (RelocIndexEntry*)_end;
|
||||||
RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size);
|
RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size);
|
||||||
assert(_addr == _code->instructions_begin(), "_addr must be unadjusted");
|
assert(_addr == _code->code_begin(), "_addr must be unadjusted");
|
||||||
int card = (begin - _addr) / indexCardSize;
|
int card = (begin - _addr) / indexCardSize;
|
||||||
if (card > 0) {
|
if (card > 0) {
|
||||||
if (index+card-1 < index_limit) index += card-1;
|
if (index+card-1 < index_limit) index += card-1;
|
||||||
@ -362,31 +377,12 @@ void RelocIterator::advance_over_prefix() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address RelocIterator::compute_section_start(int n) const {
|
void RelocIterator::initialize_misc() {
|
||||||
// This routine not only computes a section start, but also
|
set_has_current(false);
|
||||||
// memoizes it for later.
|
for (int i = (int) CodeBuffer::SECT_FIRST; i < (int) CodeBuffer::SECT_LIMIT; i++) {
|
||||||
#define CACHE ((RelocIterator*)this)->_section_start[n]
|
_section_start[i] = NULL; // these will be lazily computed, if needed
|
||||||
CodeBlob* cb = code();
|
_section_end [i] = NULL;
|
||||||
guarantee(cb != NULL, "must have a code blob");
|
|
||||||
if (n == CodeBuffer::SECT_INSTS)
|
|
||||||
return CACHE = cb->instructions_begin();
|
|
||||||
assert(cb->is_nmethod(), "only nmethods have these sections");
|
|
||||||
nmethod* nm = (nmethod*) cb;
|
|
||||||
address res = NULL;
|
|
||||||
switch (n) {
|
|
||||||
case CodeBuffer::SECT_STUBS:
|
|
||||||
res = nm->stub_begin();
|
|
||||||
break;
|
|
||||||
case CodeBuffer::SECT_CONSTS:
|
|
||||||
res = nm->consts_begin();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
}
|
||||||
assert(nm->contains(res) || res == nm->instructions_end(), "tame pointer");
|
|
||||||
CACHE = res;
|
|
||||||
return res;
|
|
||||||
#undef CACHE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -502,8 +502,7 @@ class RelocationHolder VALUE_OBJ_CLASS_SPEC {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
class RelocIterator : public StackObj {
|
class RelocIterator : public StackObj {
|
||||||
enum { SECT_CONSTS = 2,
|
enum { SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT, checked in ctor
|
||||||
SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT
|
|
||||||
friend class Relocation;
|
friend class Relocation;
|
||||||
friend class relocInfo; // for change_reloc_info_for_address only
|
friend class relocInfo; // for change_reloc_info_for_address only
|
||||||
typedef relocInfo::relocType relocType;
|
typedef relocInfo::relocType relocType;
|
||||||
@ -521,6 +520,7 @@ class RelocIterator : public StackObj {
|
|||||||
|
|
||||||
// Base addresses needed to compute targets of section_word_type relocs.
|
// Base addresses needed to compute targets of section_word_type relocs.
|
||||||
address _section_start[SECT_LIMIT];
|
address _section_start[SECT_LIMIT];
|
||||||
|
address _section_end [SECT_LIMIT];
|
||||||
|
|
||||||
void set_has_current(bool b) {
|
void set_has_current(bool b) {
|
||||||
_datalen = !b ? -1 : 0;
|
_datalen = !b ? -1 : 0;
|
||||||
@ -540,14 +540,7 @@ class RelocIterator : public StackObj {
|
|||||||
|
|
||||||
void advance_over_prefix(); // helper method
|
void advance_over_prefix(); // helper method
|
||||||
|
|
||||||
void initialize_misc() {
|
void initialize_misc();
|
||||||
set_has_current(false);
|
|
||||||
for (int i = 0; i < SECT_LIMIT; i++) {
|
|
||||||
_section_start[i] = NULL; // these will be lazily computed, if needed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
address compute_section_start(int n) const; // out-of-line helper
|
|
||||||
|
|
||||||
void initialize(nmethod* nm, address begin, address limit);
|
void initialize(nmethod* nm, address begin, address limit);
|
||||||
|
|
||||||
@ -598,11 +591,15 @@ class RelocIterator : public StackObj {
|
|||||||
bool has_current() const { return _datalen >= 0; }
|
bool has_current() const { return _datalen >= 0; }
|
||||||
|
|
||||||
void set_addr(address addr) { _addr = addr; }
|
void set_addr(address addr) { _addr = addr; }
|
||||||
bool addr_in_const() const { return addr() >= section_start(SECT_CONSTS); }
|
bool addr_in_const() const;
|
||||||
|
|
||||||
address section_start(int n) const {
|
address section_start(int n) const {
|
||||||
address res = _section_start[n];
|
assert(_section_start[n], "must be initialized");
|
||||||
return (res != NULL) ? res : compute_section_start(n);
|
return _section_start[n];
|
||||||
|
}
|
||||||
|
address section_end(int n) const {
|
||||||
|
assert(_section_end[n], "must be initialized");
|
||||||
|
return _section_end[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
// The address points to the affected displacement part of the instruction.
|
// The address points to the affected displacement part of the instruction.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -174,7 +174,7 @@ void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const {
|
|||||||
print_value_on(st);
|
print_value_on(st);
|
||||||
// decode offsets
|
// decode offsets
|
||||||
if (WizardMode) {
|
if (WizardMode) {
|
||||||
st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->instructions_begin());
|
st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->content_begin());
|
||||||
st->print_cr(" offset: %d", _decode_offset);
|
st->print_cr(" offset: %d", _decode_offset);
|
||||||
st->print_cr(" bci: %d", bci());
|
st->print_cr(" bci: %d", bci());
|
||||||
st->print_cr(" reexecute: %s", should_reexecute() ? "true" : "false");
|
st->print_cr(" reexecute: %s", should_reexecute() ? "true" : "false");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -66,9 +66,9 @@ StubQueue::StubQueue(StubInterface* stub_interface, int buffer_size,
|
|||||||
vm_exit_out_of_memory(size, err_msg("CodeCache: no room for %s", name));
|
vm_exit_out_of_memory(size, err_msg("CodeCache: no room for %s", name));
|
||||||
}
|
}
|
||||||
_stub_interface = stub_interface;
|
_stub_interface = stub_interface;
|
||||||
_buffer_size = blob->instructions_size();
|
_buffer_size = blob->content_size();
|
||||||
_buffer_limit = blob->instructions_size();
|
_buffer_limit = blob->content_size();
|
||||||
_stub_buffer = blob->instructions_begin();
|
_stub_buffer = blob->content_begin();
|
||||||
_queue_begin = 0;
|
_queue_begin = 0;
|
||||||
_queue_end = 0;
|
_queue_end = 0;
|
||||||
_number_of_stubs = 0;
|
_number_of_stubs = 0;
|
||||||
|
@ -48,7 +48,7 @@ void* VtableStub::operator new(size_t size, int code_size) {
|
|||||||
if (blob == NULL) {
|
if (blob == NULL) {
|
||||||
vm_exit_out_of_memory(bytes, "CodeCache: no room for vtable chunks");
|
vm_exit_out_of_memory(bytes, "CodeCache: no room for vtable chunks");
|
||||||
}
|
}
|
||||||
_chunk = blob->instructions_begin();
|
_chunk = blob->content_begin();
|
||||||
_chunk_end = _chunk + bytes;
|
_chunk_end = _chunk + bytes;
|
||||||
Forte::register_stub("vtable stub", _chunk, _chunk_end);
|
Forte::register_stub("vtable stub", _chunk, _chunk_end);
|
||||||
// Notify JVMTI about this stub. The event will be recorded by the enclosing
|
// Notify JVMTI about this stub. The event will be recorded by the enclosing
|
||||||
|
@ -399,7 +399,7 @@ void CompileTask::log_task_done(CompileLog* log) {
|
|||||||
// <task_done ... stamp='1.234'> </task>
|
// <task_done ... stamp='1.234'> </task>
|
||||||
nmethod* nm = code();
|
nmethod* nm = code();
|
||||||
log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
|
log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
|
||||||
_is_success, nm == NULL ? 0 : nm->instructions_size(),
|
_is_success, nm == NULL ? 0 : nm->content_size(),
|
||||||
method->invocation_count());
|
method->invocation_count());
|
||||||
int bec = method->backedge_count();
|
int bec = method->backedge_count();
|
||||||
if (bec != 0) log->print(" backedge_count='%d'", bec);
|
if (bec != 0) log->print(" backedge_count='%d'", bec);
|
||||||
@ -1847,13 +1847,13 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Collect counts of successful compilations
|
// Collect counts of successful compilations
|
||||||
_sum_nmethod_size += code->total_size();
|
_sum_nmethod_size += code->total_size();
|
||||||
_sum_nmethod_code_size += code->code_size();
|
_sum_nmethod_code_size += code->insts_size();
|
||||||
_total_compile_count++;
|
_total_compile_count++;
|
||||||
|
|
||||||
if (UsePerfData) {
|
if (UsePerfData) {
|
||||||
_perf_sum_nmethod_size->inc(code->total_size());
|
_perf_sum_nmethod_size->inc( code->total_size());
|
||||||
_perf_sum_nmethod_code_size->inc(code->code_size());
|
_perf_sum_nmethod_code_size->inc(code->insts_size());
|
||||||
_perf_total_compile_count->inc();
|
_perf_total_compile_count->inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) {
|
|||||||
if (!load_library()) return;
|
if (!load_library()) return;
|
||||||
decode_env env(cb, st);
|
decode_env env(cb, st);
|
||||||
env.output()->print_cr("Decoding CodeBlob " INTPTR_FORMAT, cb);
|
env.output()->print_cr("Decoding CodeBlob " INTPTR_FORMAT, cb);
|
||||||
env.decode_instructions(cb->instructions_begin(), cb->instructions_end());
|
env.decode_instructions(cb->code_begin(), cb->code_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -424,12 +424,12 @@ void Disassembler::decode(nmethod* nm, outputStream* st) {
|
|||||||
env.output()->print_cr("Code:");
|
env.output()->print_cr("Code:");
|
||||||
|
|
||||||
#ifdef SHARK
|
#ifdef SHARK
|
||||||
SharkEntry* entry = (SharkEntry *) nm->instructions_begin();
|
SharkEntry* entry = (SharkEntry *) nm->code_begin();
|
||||||
unsigned char* p = entry->code_start();
|
unsigned char* p = entry->code_start();
|
||||||
unsigned char* end = entry->code_limit();
|
unsigned char* end = entry->code_limit();
|
||||||
#else
|
#else
|
||||||
unsigned char* p = nm->instructions_begin();
|
unsigned char* p = nm->code_begin();
|
||||||
unsigned char* end = nm->instructions_end();
|
unsigned char* end = nm->code_end();
|
||||||
#endif // SHARK
|
#endif // SHARK
|
||||||
|
|
||||||
// If there has been profiling, print the buckets.
|
// If there has been profiling, print the buckets.
|
||||||
|
@ -504,6 +504,7 @@ graphKit.hpp addnode.hpp
|
|||||||
graphKit.hpp callnode.hpp
|
graphKit.hpp callnode.hpp
|
||||||
graphKit.hpp cfgnode.hpp
|
graphKit.hpp cfgnode.hpp
|
||||||
graphKit.hpp ciEnv.hpp
|
graphKit.hpp ciEnv.hpp
|
||||||
|
graphKit.hpp ciMethodData.hpp
|
||||||
graphKit.hpp divnode.hpp
|
graphKit.hpp divnode.hpp
|
||||||
graphKit.hpp compile.hpp
|
graphKit.hpp compile.hpp
|
||||||
graphKit.hpp deoptimization.hpp
|
graphKit.hpp deoptimization.hpp
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -117,7 +117,7 @@ class CodeletMark: ResourceMark {
|
|||||||
|
|
||||||
|
|
||||||
// commit Codelet
|
// commit Codelet
|
||||||
AbstractInterpreter::code()->commit((*_masm)->code()->pure_code_size());
|
AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size());
|
||||||
// make sure nobody can use _masm outside a CodeletMark lifespan
|
// make sure nobody can use _masm outside a CodeletMark lifespan
|
||||||
*_masm = NULL;
|
*_masm = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1124,7 +1124,7 @@ address SignatureHandlerLibrary::set_handler_blob() {
|
|||||||
if (handler_blob == NULL) {
|
if (handler_blob == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
address handler = handler_blob->instructions_begin();
|
address handler = handler_blob->code_begin();
|
||||||
_handler_blob = handler_blob;
|
_handler_blob = handler_blob;
|
||||||
_handler = handler;
|
_handler = handler;
|
||||||
return handler;
|
return handler;
|
||||||
@ -1140,7 +1140,7 @@ void SignatureHandlerLibrary::initialize() {
|
|||||||
|
|
||||||
BufferBlob* bb = BufferBlob::create("Signature Handler Temp Buffer",
|
BufferBlob* bb = BufferBlob::create("Signature Handler Temp Buffer",
|
||||||
SignatureHandlerLibrary::buffer_size);
|
SignatureHandlerLibrary::buffer_size);
|
||||||
_buffer = bb->instructions_begin();
|
_buffer = bb->code_begin();
|
||||||
|
|
||||||
_fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true);
|
_fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true);
|
||||||
_handlers = new(ResourceObj::C_HEAP)GrowableArray<address>(32, true);
|
_handlers = new(ResourceObj::C_HEAP)GrowableArray<address>(32, true);
|
||||||
@ -1148,16 +1148,16 @@ void SignatureHandlerLibrary::initialize() {
|
|||||||
|
|
||||||
address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) {
|
address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) {
|
||||||
address handler = _handler;
|
address handler = _handler;
|
||||||
int code_size = buffer->pure_code_size();
|
int insts_size = buffer->pure_insts_size();
|
||||||
if (handler + code_size > _handler_blob->instructions_end()) {
|
if (handler + insts_size > _handler_blob->code_end()) {
|
||||||
// get a new handler blob
|
// get a new handler blob
|
||||||
handler = set_handler_blob();
|
handler = set_handler_blob();
|
||||||
}
|
}
|
||||||
if (handler != NULL) {
|
if (handler != NULL) {
|
||||||
memcpy(handler, buffer->code_begin(), code_size);
|
memcpy(handler, buffer->insts_begin(), insts_size);
|
||||||
pd_set_handler(handler);
|
pd_set_handler(handler);
|
||||||
ICache::invalidate_range(handler, code_size);
|
ICache::invalidate_range(handler, insts_size);
|
||||||
_handler = handler + code_size;
|
_handler = handler + insts_size;
|
||||||
}
|
}
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
@ -1196,8 +1196,8 @@ void SignatureHandlerLibrary::add(methodHandle method) {
|
|||||||
(method->is_static() ? "static" : "receiver"),
|
(method->is_static() ? "static" : "receiver"),
|
||||||
method->name_and_sig_as_C_string(),
|
method->name_and_sig_as_C_string(),
|
||||||
fingerprint,
|
fingerprint,
|
||||||
buffer.code_size());
|
buffer.insts_size());
|
||||||
Disassembler::decode(handler, handler + buffer.code_size());
|
Disassembler::decode(handler, handler + buffer.insts_size());
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
tty->print_cr(" --- associated result handler ---");
|
tty->print_cr(" --- associated result handler ---");
|
||||||
address rh_begin = Interpreter::result_handler(method()->result_type());
|
address rh_begin = Interpreter::result_handler(method()->result_type());
|
||||||
|
@ -58,7 +58,7 @@ void* ResourceObj::operator new(size_t size, allocation_type type) {
|
|||||||
void ResourceObj::operator delete(void* p) {
|
void ResourceObj::operator delete(void* p) {
|
||||||
assert(((ResourceObj *)p)->allocated_on_C_heap(),
|
assert(((ResourceObj *)p)->allocated_on_C_heap(),
|
||||||
"delete only allowed for C_HEAP objects");
|
"delete only allowed for C_HEAP objects");
|
||||||
DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t) badHeapOopVal;)
|
DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t)badHeapOopVal;)
|
||||||
FreeHeap(p);
|
FreeHeap(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assi
|
|||||||
ResourceObj::~ResourceObj() {
|
ResourceObj::~ResourceObj() {
|
||||||
// allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
|
// allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
|
||||||
if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap.
|
if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap.
|
||||||
_allocation = (uintptr_t) badHeapOopVal; // zap type
|
_allocation = (uintptr_t)badHeapOopVal; // zap type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ASSERT
|
#endif // ASSERT
|
||||||
|
@ -163,7 +163,8 @@ class BlockOffsetSharedArray: public CHeapObj {
|
|||||||
size_t i = index_for(left);
|
size_t i = index_for(left);
|
||||||
const size_t end = i + num_cards;
|
const size_t end = i + num_cards;
|
||||||
for (; i < end; i++) {
|
for (; i < end; i++) {
|
||||||
assert(!reducing || _offset_array[i] >= offset, "Not reducing");
|
// Elided until CR 6977974 is fixed properly.
|
||||||
|
// assert(!reducing || _offset_array[i] >= offset, "Not reducing");
|
||||||
_offset_array[i] = offset;
|
_offset_array[i] = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +185,8 @@ class BlockOffsetSharedArray: public CHeapObj {
|
|||||||
size_t i = left;
|
size_t i = left;
|
||||||
const size_t end = i + num_cards;
|
const size_t end = i + num_cards;
|
||||||
for (; i < end; i++) {
|
for (; i < end; i++) {
|
||||||
assert(!reducing || _offset_array[i] >= offset, "Not reducing");
|
// Elided until CR 6977974 is fixed properly.
|
||||||
|
// assert(!reducing || _offset_array[i] >= offset, "Not reducing");
|
||||||
_offset_array[i] = offset;
|
_offset_array[i] = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ void Compile::init_scratch_buffer_blob() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the relocation buffers
|
// Initialize the relocation buffers
|
||||||
relocInfo* locs_buf = (relocInfo*) blob->instructions_end() - MAX_locs_size;
|
relocInfo* locs_buf = (relocInfo*) blob->content_end() - MAX_locs_size;
|
||||||
set_scratch_locs_memory(locs_buf);
|
set_scratch_locs_memory(locs_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,9 +422,9 @@ uint Compile::scratch_emit_size(const Node* n) {
|
|||||||
assert(blob != NULL, "Initialize BufferBlob at start");
|
assert(blob != NULL, "Initialize BufferBlob at start");
|
||||||
assert(blob->size() > MAX_inst_size, "sanity");
|
assert(blob->size() > MAX_inst_size, "sanity");
|
||||||
relocInfo* locs_buf = scratch_locs_memory();
|
relocInfo* locs_buf = scratch_locs_memory();
|
||||||
address blob_begin = blob->instructions_begin();
|
address blob_begin = blob->content_begin();
|
||||||
address blob_end = (address)locs_buf;
|
address blob_end = (address)locs_buf;
|
||||||
assert(blob->instructions_contains(blob_end), "sanity");
|
assert(blob->content_contains(blob_end), "sanity");
|
||||||
CodeBuffer buf(blob_begin, blob_end - blob_begin);
|
CodeBuffer buf(blob_begin, blob_end - blob_begin);
|
||||||
buf.initialize_consts_size(MAX_const_size);
|
buf.initialize_consts_size(MAX_const_size);
|
||||||
buf.initialize_stubs_size(MAX_stubs_size);
|
buf.initialize_stubs_size(MAX_stubs_size);
|
||||||
@ -433,7 +433,7 @@ uint Compile::scratch_emit_size(const Node* n) {
|
|||||||
buf.insts()->initialize_shared_locs(&locs_buf[0], lsize);
|
buf.insts()->initialize_shared_locs(&locs_buf[0], lsize);
|
||||||
buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize);
|
buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize);
|
||||||
n->emit(buf, this->regalloc());
|
n->emit(buf, this->regalloc());
|
||||||
return buf.code_size();
|
return buf.insts_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1891,7 +1891,7 @@ void GraphKit::uncommon_trap(int trap_request,
|
|||||||
kill_dead_locals();
|
kill_dead_locals();
|
||||||
|
|
||||||
// Now insert the uncommon trap subroutine call
|
// Now insert the uncommon trap subroutine call
|
||||||
address call_addr = SharedRuntime::uncommon_trap_blob()->instructions_begin();
|
address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
|
||||||
const TypePtr* no_memory_effects = NULL;
|
const TypePtr* no_memory_effects = NULL;
|
||||||
// Pass the index of the class to be loaded
|
// Pass the index of the class to be loaded
|
||||||
Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON |
|
Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON |
|
||||||
@ -2451,11 +2451,79 @@ Node* GraphKit::type_check_receiver(Node* receiver, ciKlass* klass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------seems_never_null-------------------------------
|
||||||
|
// Use null_seen information if it is available from the profile.
|
||||||
|
// If we see an unexpected null at a type check we record it and force a
|
||||||
|
// recompile; the offending check will be recompiled to handle NULLs.
|
||||||
|
// If we see several offending BCIs, then all checks in the
|
||||||
|
// method will be recompiled.
|
||||||
|
bool GraphKit::seems_never_null(Node* obj, ciProfileData* data) {
|
||||||
|
if (UncommonNullCast // Cutout for this technique
|
||||||
|
&& obj != null() // And not the -Xcomp stupid case?
|
||||||
|
&& !too_many_traps(Deoptimization::Reason_null_check)
|
||||||
|
) {
|
||||||
|
if (data == NULL)
|
||||||
|
// Edge case: no mature data. Be optimistic here.
|
||||||
|
return true;
|
||||||
|
// If the profile has not seen a null, assume it won't happen.
|
||||||
|
assert(java_bc() == Bytecodes::_checkcast ||
|
||||||
|
java_bc() == Bytecodes::_instanceof ||
|
||||||
|
java_bc() == Bytecodes::_aastore, "MDO must collect null_seen bit here");
|
||||||
|
return !data->as_BitData()->null_seen();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------maybe_cast_profiled_receiver-------------------------
|
||||||
|
// If the profile has seen exactly one type, narrow to exactly that type.
|
||||||
|
// Subsequent type checks will always fold up.
|
||||||
|
Node* GraphKit::maybe_cast_profiled_receiver(Node* not_null_obj,
|
||||||
|
ciProfileData* data,
|
||||||
|
ciKlass* require_klass) {
|
||||||
|
if (!UseTypeProfile || !TypeProfileCasts) return NULL;
|
||||||
|
if (data == NULL) return NULL;
|
||||||
|
|
||||||
|
// Make sure we haven't already deoptimized from this tactic.
|
||||||
|
if (too_many_traps(Deoptimization::Reason_class_check))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// (No, this isn't a call, but it's enough like a virtual call
|
||||||
|
// to use the same ciMethod accessor to get the profile info...)
|
||||||
|
ciCallProfile profile = method()->call_profile_at_bci(bci());
|
||||||
|
if (profile.count() >= 0 && // no cast failures here
|
||||||
|
profile.has_receiver(0) &&
|
||||||
|
profile.morphism() == 1) {
|
||||||
|
ciKlass* exact_kls = profile.receiver(0);
|
||||||
|
if (require_klass == NULL ||
|
||||||
|
static_subtype_check(require_klass, exact_kls) == SSC_always_true) {
|
||||||
|
// If we narrow the type to match what the type profile sees,
|
||||||
|
// we can then remove the rest of the cast.
|
||||||
|
// This is a win, even if the exact_kls is very specific,
|
||||||
|
// because downstream operations, such as method calls,
|
||||||
|
// will often benefit from the sharper type.
|
||||||
|
Node* exact_obj = not_null_obj; // will get updated in place...
|
||||||
|
Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0,
|
||||||
|
&exact_obj);
|
||||||
|
{ PreserveJVMState pjvms(this);
|
||||||
|
set_control(slow_ctl);
|
||||||
|
uncommon_trap(Deoptimization::Reason_class_check,
|
||||||
|
Deoptimization::Action_maybe_recompile);
|
||||||
|
}
|
||||||
|
replace_in_map(not_null_obj, exact_obj);
|
||||||
|
return exact_obj;
|
||||||
|
}
|
||||||
|
// assert(ssc == SSC_always_true)... except maybe the profile lied to us.
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------gen_instanceof--------------------------------
|
//-------------------------------gen_instanceof--------------------------------
|
||||||
// Generate an instance-of idiom. Used by both the instance-of bytecode
|
// Generate an instance-of idiom. Used by both the instance-of bytecode
|
||||||
// and the reflective instance-of call.
|
// and the reflective instance-of call.
|
||||||
Node* GraphKit::gen_instanceof( Node *subobj, Node* superklass ) {
|
Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) {
|
||||||
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
kill_dead_locals(); // Benefit all the uncommon traps
|
||||||
assert( !stopped(), "dead parse path should be checked in callers" );
|
assert( !stopped(), "dead parse path should be checked in callers" );
|
||||||
assert(!TypePtr::NULL_PTR->higher_equal(_gvn.type(superklass)->is_klassptr()),
|
assert(!TypePtr::NULL_PTR->higher_equal(_gvn.type(superklass)->is_klassptr()),
|
||||||
"must check for not-null not-dead klass in callers");
|
"must check for not-null not-dead klass in callers");
|
||||||
@ -2466,9 +2534,16 @@ Node* GraphKit::gen_instanceof( Node *subobj, Node* superklass ) {
|
|||||||
Node* phi = new(C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL);
|
Node* phi = new(C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL);
|
||||||
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
||||||
|
|
||||||
|
ciProfileData* data = NULL;
|
||||||
|
if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode
|
||||||
|
data = method()->method_data()->bci_to_data(bci());
|
||||||
|
}
|
||||||
|
bool never_see_null = (ProfileDynamicTypes // aggressive use of profile
|
||||||
|
&& seems_never_null(obj, data));
|
||||||
|
|
||||||
// Null check; get casted pointer; set region slot 3
|
// Null check; get casted pointer; set region slot 3
|
||||||
Node* null_ctl = top();
|
Node* null_ctl = top();
|
||||||
Node* not_null_obj = null_check_oop(subobj, &null_ctl);
|
Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
|
||||||
|
|
||||||
// If not_null_obj is dead, only null-path is taken
|
// If not_null_obj is dead, only null-path is taken
|
||||||
if (stopped()) { // Doing instance-of on a NULL?
|
if (stopped()) { // Doing instance-of on a NULL?
|
||||||
@ -2477,6 +2552,23 @@ Node* GraphKit::gen_instanceof( Node *subobj, Node* superklass ) {
|
|||||||
}
|
}
|
||||||
region->init_req(_null_path, null_ctl);
|
region->init_req(_null_path, null_ctl);
|
||||||
phi ->init_req(_null_path, intcon(0)); // Set null path value
|
phi ->init_req(_null_path, intcon(0)); // Set null path value
|
||||||
|
if (null_ctl == top()) {
|
||||||
|
// Do this eagerly, so that pattern matches like is_diamond_phi
|
||||||
|
// will work even during parsing.
|
||||||
|
assert(_null_path == PATH_LIMIT-1, "delete last");
|
||||||
|
region->del_req(_null_path);
|
||||||
|
phi ->del_req(_null_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProfileDynamicTypes && data != NULL) {
|
||||||
|
Node* cast_obj = maybe_cast_profiled_receiver(not_null_obj, data, NULL);
|
||||||
|
if (stopped()) { // Profile disagrees with this path.
|
||||||
|
set_control(null_ctl); // Null is the only remaining possibility.
|
||||||
|
return intcon(0);
|
||||||
|
}
|
||||||
|
if (cast_obj != NULL)
|
||||||
|
not_null_obj = cast_obj;
|
||||||
|
}
|
||||||
|
|
||||||
// Load the object's klass
|
// Load the object's klass
|
||||||
Node* obj_klass = load_object_klass(not_null_obj);
|
Node* obj_klass = load_object_klass(not_null_obj);
|
||||||
@ -2546,20 +2638,8 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
|
|||||||
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
||||||
|
|
||||||
// Use null-cast information if it is available
|
// Use null-cast information if it is available
|
||||||
bool never_see_null = false;
|
bool never_see_null = ((failure_control == NULL) // regular case only
|
||||||
// If we see an unexpected null at a check-cast we record it and force a
|
&& seems_never_null(obj, data));
|
||||||
// recompile; the offending check-cast will be compiled to handle NULLs.
|
|
||||||
// If we see several offending BCIs, then all checkcasts in the
|
|
||||||
// method will be compiled to handle NULLs.
|
|
||||||
if (UncommonNullCast // Cutout for this technique
|
|
||||||
&& failure_control == NULL // regular case
|
|
||||||
&& obj != null() // And not the -Xcomp stupid case?
|
|
||||||
&& !too_many_traps(Deoptimization::Reason_null_check)) {
|
|
||||||
// Finally, check the "null_seen" bit from the interpreter.
|
|
||||||
if (data == NULL || !data->as_BitData()->null_seen()) {
|
|
||||||
never_see_null = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Null check; get casted pointer; set region slot 3
|
// Null check; get casted pointer; set region slot 3
|
||||||
Node* null_ctl = top();
|
Node* null_ctl = top();
|
||||||
@ -2572,47 +2652,26 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
|
|||||||
}
|
}
|
||||||
region->init_req(_null_path, null_ctl);
|
region->init_req(_null_path, null_ctl);
|
||||||
phi ->init_req(_null_path, null()); // Set null path value
|
phi ->init_req(_null_path, null()); // Set null path value
|
||||||
|
if (null_ctl == top()) {
|
||||||
|
// Do this eagerly, so that pattern matches like is_diamond_phi
|
||||||
|
// will work even during parsing.
|
||||||
|
assert(_null_path == PATH_LIMIT-1, "delete last");
|
||||||
|
region->del_req(_null_path);
|
||||||
|
phi ->del_req(_null_path);
|
||||||
|
}
|
||||||
|
|
||||||
Node* cast_obj = NULL; // the casted version of the object
|
Node* cast_obj = NULL;
|
||||||
|
if (data != NULL &&
|
||||||
// If the profile has seen exactly one type, narrow to that type.
|
|
||||||
// (The subsequent subtype check will always fold up.)
|
|
||||||
if (UseTypeProfile && TypeProfileCasts && data != NULL &&
|
|
||||||
// Counter has never been decremented (due to cast failure).
|
// Counter has never been decremented (due to cast failure).
|
||||||
// ...This is a reasonable thing to expect. It is true of
|
// ...This is a reasonable thing to expect. It is true of
|
||||||
// all casts inserted by javac to implement generic types.
|
// all casts inserted by javac to implement generic types.
|
||||||
data->as_CounterData()->count() >= 0 &&
|
data->as_CounterData()->count() >= 0) {
|
||||||
!too_many_traps(Deoptimization::Reason_class_check)) {
|
cast_obj = maybe_cast_profiled_receiver(not_null_obj, data, tk->klass());
|
||||||
// (No, this isn't a call, but it's enough like a virtual call
|
if (cast_obj != NULL) {
|
||||||
// to use the same ciMethod accessor to get the profile info...)
|
if (failure_control != NULL) // failure is now impossible
|
||||||
ciCallProfile profile = method()->call_profile_at_bci(bci());
|
(*failure_control) = top();
|
||||||
if (profile.count() >= 0 && // no cast failures here
|
// adjust the type of the phi to the exact klass:
|
||||||
profile.has_receiver(0) &&
|
phi->raise_bottom_type(_gvn.type(cast_obj)->meet(TypePtr::NULL_PTR));
|
||||||
profile.morphism() == 1) {
|
|
||||||
ciKlass* exact_kls = profile.receiver(0);
|
|
||||||
int ssc = static_subtype_check(tk->klass(), exact_kls);
|
|
||||||
if (ssc == SSC_always_true) {
|
|
||||||
// If we narrow the type to match what the type profile sees,
|
|
||||||
// we can then remove the rest of the cast.
|
|
||||||
// This is a win, even if the exact_kls is very specific,
|
|
||||||
// because downstream operations, such as method calls,
|
|
||||||
// will often benefit from the sharper type.
|
|
||||||
Node* exact_obj = not_null_obj; // will get updated in place...
|
|
||||||
Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0,
|
|
||||||
&exact_obj);
|
|
||||||
{ PreserveJVMState pjvms(this);
|
|
||||||
set_control(slow_ctl);
|
|
||||||
uncommon_trap(Deoptimization::Reason_class_check,
|
|
||||||
Deoptimization::Action_maybe_recompile);
|
|
||||||
}
|
|
||||||
if (failure_control != NULL) // failure is now impossible
|
|
||||||
(*failure_control) = top();
|
|
||||||
replace_in_map(not_null_obj, exact_obj);
|
|
||||||
// adjust the type of the phi to the exact klass:
|
|
||||||
phi->raise_bottom_type(_gvn.type(exact_obj)->meet(TypePtr::NULL_PTR));
|
|
||||||
cast_obj = exact_obj;
|
|
||||||
}
|
|
||||||
// assert(cast_obj != NULL)... except maybe the profile lied to us.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +341,14 @@ class GraphKit : public Phase {
|
|||||||
Node* null_check_oop(Node* value, Node* *null_control,
|
Node* null_check_oop(Node* value, Node* *null_control,
|
||||||
bool never_see_null = false);
|
bool never_see_null = false);
|
||||||
|
|
||||||
|
// Check the null_seen bit.
|
||||||
|
bool seems_never_null(Node* obj, ciProfileData* data);
|
||||||
|
|
||||||
|
// Use the type profile to narrow an object type.
|
||||||
|
Node* maybe_cast_profiled_receiver(Node* not_null_obj,
|
||||||
|
ciProfileData* data,
|
||||||
|
ciKlass* require_klass);
|
||||||
|
|
||||||
// Cast obj to not-null on this path
|
// Cast obj to not-null on this path
|
||||||
Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
|
Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
|
||||||
// Replace all occurrences of one node by another.
|
// Replace all occurrences of one node by another.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -72,8 +72,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
|
|||||||
for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) {
|
for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) {
|
||||||
Node* nn = null_block->_nodes[i1];
|
Node* nn = null_block->_nodes[i1];
|
||||||
if (nn->is_MachCall() &&
|
if (nn->is_MachCall() &&
|
||||||
nn->as_MachCall()->entry_point() ==
|
nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) {
|
||||||
SharedRuntime::uncommon_trap_blob()->instructions_begin()) {
|
|
||||||
const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type();
|
const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type();
|
||||||
if (trtype->isa_int() && trtype->is_int()->is_con()) {
|
if (trtype->isa_int() && trtype->is_int()->is_con()) {
|
||||||
jint tr_con = trtype->is_int()->get_con();
|
jint tr_con = trtype->is_int()->get_con();
|
||||||
|
@ -906,7 +906,8 @@ bool LibraryCallKit::inline_string_equals() {
|
|||||||
const int count_offset = java_lang_String::count_offset_in_bytes();
|
const int count_offset = java_lang_String::count_offset_in_bytes();
|
||||||
const int offset_offset = java_lang_String::offset_offset_in_bytes();
|
const int offset_offset = java_lang_String::offset_offset_in_bytes();
|
||||||
|
|
||||||
_sp += 2;
|
int nargs = 2;
|
||||||
|
_sp += nargs;
|
||||||
Node* argument = pop(); // pop non-receiver first: it was pushed second
|
Node* argument = pop(); // pop non-receiver first: it was pushed second
|
||||||
Node* receiver = pop();
|
Node* receiver = pop();
|
||||||
|
|
||||||
@ -914,11 +915,11 @@ bool LibraryCallKit::inline_string_equals() {
|
|||||||
// null check technically happens in the wrong place, which can lead to
|
// null check technically happens in the wrong place, which can lead to
|
||||||
// invalid stack traces when string compare is inlined into a method
|
// invalid stack traces when string compare is inlined into a method
|
||||||
// which handles NullPointerExceptions.
|
// which handles NullPointerExceptions.
|
||||||
_sp += 2;
|
_sp += nargs;
|
||||||
receiver = do_null_check(receiver, T_OBJECT);
|
receiver = do_null_check(receiver, T_OBJECT);
|
||||||
//should not do null check for argument for String.equals(), because spec
|
//should not do null check for argument for String.equals(), because spec
|
||||||
//allows to specify NULL as argument.
|
//allows to specify NULL as argument.
|
||||||
_sp -= 2;
|
_sp -= nargs;
|
||||||
|
|
||||||
if (stopped()) {
|
if (stopped()) {
|
||||||
return true;
|
return true;
|
||||||
@ -943,7 +944,9 @@ bool LibraryCallKit::inline_string_equals() {
|
|||||||
ciInstanceKlass* klass = env()->String_klass();
|
ciInstanceKlass* klass = env()->String_klass();
|
||||||
|
|
||||||
if (!stopped()) {
|
if (!stopped()) {
|
||||||
|
_sp += nargs; // gen_instanceof might do an uncommon trap
|
||||||
Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
|
Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
|
||||||
|
_sp -= nargs;
|
||||||
Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
|
Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
|
||||||
Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
|
Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
|
||||||
|
|
||||||
@ -2935,7 +2938,9 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
|
|||||||
switch (id) {
|
switch (id) {
|
||||||
case vmIntrinsics::_isInstance:
|
case vmIntrinsics::_isInstance:
|
||||||
// nothing is an instance of a primitive type
|
// nothing is an instance of a primitive type
|
||||||
|
_sp += nargs; // gen_instanceof might do an uncommon trap
|
||||||
query_value = gen_instanceof(obj, kls);
|
query_value = gen_instanceof(obj, kls);
|
||||||
|
_sp -= nargs;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vmIntrinsics::_getModifiers:
|
case vmIntrinsics::_getModifiers:
|
||||||
@ -4957,8 +4962,7 @@ LibraryCallKit::tightly_coupled_allocation(Node* ptr,
|
|||||||
for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) {
|
for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) {
|
||||||
Node* obs = not_ctl->fast_out(j);
|
Node* obs = not_ctl->fast_out(j);
|
||||||
if (obs->in(0) == not_ctl && obs->is_Call() &&
|
if (obs->in(0) == not_ctl && obs->is_Call() &&
|
||||||
(obs->as_Call()->entry_point() ==
|
(obs->as_Call()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) {
|
||||||
SharedRuntime::uncommon_trap_blob()->instructions_begin())) {
|
|
||||||
found_trap = true; break;
|
found_trap = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1184,7 +1184,7 @@ void Compile::Fill_buffer() {
|
|||||||
MacroAssembler(cb).bind( blk_labels[b->_pre_order] );
|
MacroAssembler(cb).bind( blk_labels[b->_pre_order] );
|
||||||
|
|
||||||
else
|
else
|
||||||
assert( blk_labels[b->_pre_order].loc_pos() == cb->code_size(),
|
assert( blk_labels[b->_pre_order].loc_pos() == cb->insts_size(),
|
||||||
"label position does not match code offset" );
|
"label position does not match code offset" );
|
||||||
|
|
||||||
uint last_inst = b->_nodes.size();
|
uint last_inst = b->_nodes.size();
|
||||||
@ -1225,7 +1225,7 @@ void Compile::Fill_buffer() {
|
|||||||
// If this requires all previous instructions be flushed, then do so
|
// If this requires all previous instructions be flushed, then do so
|
||||||
if( is_sfn || is_mcall || mach->alignment_required() != 1) {
|
if( is_sfn || is_mcall || mach->alignment_required() != 1) {
|
||||||
cb->flush_bundle(true);
|
cb->flush_bundle(true);
|
||||||
current_offset = cb->code_size();
|
current_offset = cb->insts_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// align the instruction if necessary
|
// align the instruction if necessary
|
||||||
@ -1246,7 +1246,7 @@ void Compile::Fill_buffer() {
|
|||||||
_cfg->_bbs.map( nop->_idx, b );
|
_cfg->_bbs.map( nop->_idx, b );
|
||||||
nop->emit(*cb, _regalloc);
|
nop->emit(*cb, _regalloc);
|
||||||
cb->flush_bundle(true);
|
cb->flush_bundle(true);
|
||||||
current_offset = cb->code_size();
|
current_offset = cb->insts_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember the start of the last call in a basic block
|
// Remember the start of the last call in a basic block
|
||||||
@ -1348,12 +1348,12 @@ void Compile::Fill_buffer() {
|
|||||||
// Save the offset for the listing
|
// Save the offset for the listing
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if( node_offsets && n->_idx < node_offset_limit )
|
if( node_offsets && n->_idx < node_offset_limit )
|
||||||
node_offsets[n->_idx] = cb->code_size();
|
node_offsets[n->_idx] = cb->insts_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// "Normal" instruction case
|
// "Normal" instruction case
|
||||||
n->emit(*cb, _regalloc);
|
n->emit(*cb, _regalloc);
|
||||||
current_offset = cb->code_size();
|
current_offset = cb->insts_size();
|
||||||
non_safepoints.observe_instruction(n, current_offset);
|
non_safepoints.observe_instruction(n, current_offset);
|
||||||
|
|
||||||
// mcall is last "call" that can be a safepoint
|
// mcall is last "call" that can be a safepoint
|
||||||
@ -1372,13 +1372,12 @@ void Compile::Fill_buffer() {
|
|||||||
assert(delay_slot != NULL, "expecting delay slot node");
|
assert(delay_slot != NULL, "expecting delay slot node");
|
||||||
|
|
||||||
// Back up 1 instruction
|
// Back up 1 instruction
|
||||||
cb->set_code_end(
|
cb->set_insts_end(cb->insts_end() - Pipeline::instr_unit_size());
|
||||||
cb->code_end()-Pipeline::instr_unit_size());
|
|
||||||
|
|
||||||
// Save the offset for the listing
|
// Save the offset for the listing
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if( node_offsets && delay_slot->_idx < node_offset_limit )
|
if( node_offsets && delay_slot->_idx < node_offset_limit )
|
||||||
node_offsets[delay_slot->_idx] = cb->code_size();
|
node_offsets[delay_slot->_idx] = cb->insts_size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Support a SafePoint in the delay slot
|
// Support a SafePoint in the delay slot
|
||||||
@ -1420,7 +1419,7 @@ void Compile::Fill_buffer() {
|
|||||||
b->_nodes.insert( b->_nodes.size(), nop );
|
b->_nodes.insert( b->_nodes.size(), nop );
|
||||||
_cfg->_bbs.map( nop->_idx, b );
|
_cfg->_bbs.map( nop->_idx, b );
|
||||||
nop->emit(*cb, _regalloc);
|
nop->emit(*cb, _regalloc);
|
||||||
current_offset = cb->code_size();
|
current_offset = cb->insts_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1437,13 +1436,13 @@ void Compile::Fill_buffer() {
|
|||||||
// Compute the size of the first block
|
// Compute the size of the first block
|
||||||
_first_block_size = blk_labels[1].loc_pos() - blk_labels[0].loc_pos();
|
_first_block_size = blk_labels[1].loc_pos() - blk_labels[0].loc_pos();
|
||||||
|
|
||||||
assert(cb->code_size() < 500000, "method is unreasonably large");
|
assert(cb->insts_size() < 500000, "method is unreasonably large");
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
// Information on the size of the method, without the extraneous code
|
// Information on the size of the method, without the extraneous code
|
||||||
Scheduling::increment_method_size(cb->code_size());
|
Scheduling::increment_method_size(cb->insts_size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
|
@ -494,6 +494,7 @@ class Parse : public GraphKit {
|
|||||||
float dynamic_branch_prediction(float &cnt);
|
float dynamic_branch_prediction(float &cnt);
|
||||||
float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci);
|
float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci);
|
||||||
bool seems_never_taken(float prob);
|
bool seems_never_taken(float prob);
|
||||||
|
bool seems_stable_comparison(BoolTest::mask btest, Node* c);
|
||||||
|
|
||||||
void do_ifnull(BoolTest::mask btest, Node* c);
|
void do_ifnull(BoolTest::mask btest, Node* c);
|
||||||
void do_if(BoolTest::mask btest, Node* c);
|
void do_if(BoolTest::mask btest, Node* c);
|
||||||
|
@ -892,6 +892,62 @@ bool Parse::seems_never_taken(float prob) {
|
|||||||
return prob < PROB_MIN;
|
return prob < PROB_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// True if the comparison seems to be the kind that will not change its
|
||||||
|
// statistics from true to false. See comments in adjust_map_after_if.
|
||||||
|
// This question is only asked along paths which are already
|
||||||
|
// classifed as untaken (by seems_never_taken), so really,
|
||||||
|
// if a path is never taken, its controlling comparison is
|
||||||
|
// already acting in a stable fashion. If the comparison
|
||||||
|
// seems stable, we will put an expensive uncommon trap
|
||||||
|
// on the untaken path. To be conservative, and to allow
|
||||||
|
// partially executed counted loops to be compiled fully,
|
||||||
|
// we will plant uncommon traps only after pointer comparisons.
|
||||||
|
bool Parse::seems_stable_comparison(BoolTest::mask btest, Node* cmp) {
|
||||||
|
for (int depth = 4; depth > 0; depth--) {
|
||||||
|
// The following switch can find CmpP here over half the time for
|
||||||
|
// dynamic language code rich with type tests.
|
||||||
|
// Code using counted loops or array manipulations (typical
|
||||||
|
// of benchmarks) will have many (>80%) CmpI instructions.
|
||||||
|
switch (cmp->Opcode()) {
|
||||||
|
case Op_CmpP:
|
||||||
|
// A never-taken null check looks like CmpP/BoolTest::eq.
|
||||||
|
// These certainly should be closed off as uncommon traps.
|
||||||
|
if (btest == BoolTest::eq)
|
||||||
|
return true;
|
||||||
|
// A never-failed type check looks like CmpP/BoolTest::ne.
|
||||||
|
// Let's put traps on those, too, so that we don't have to compile
|
||||||
|
// unused paths with indeterminate dynamic type information.
|
||||||
|
if (ProfileDynamicTypes)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case Op_CmpI:
|
||||||
|
// A small minority (< 10%) of CmpP are masked as CmpI,
|
||||||
|
// as if by boolean conversion ((p == q? 1: 0) != 0).
|
||||||
|
// Detect that here, even if it hasn't optimized away yet.
|
||||||
|
// Specifically, this covers the 'instanceof' operator.
|
||||||
|
if (btest == BoolTest::ne || btest == BoolTest::eq) {
|
||||||
|
if (_gvn.type(cmp->in(2))->singleton() &&
|
||||||
|
cmp->in(1)->is_Phi()) {
|
||||||
|
PhiNode* phi = cmp->in(1)->as_Phi();
|
||||||
|
int true_path = phi->is_diamond_phi();
|
||||||
|
if (true_path > 0 &&
|
||||||
|
_gvn.type(phi->in(1))->singleton() &&
|
||||||
|
_gvn.type(phi->in(2))->singleton()) {
|
||||||
|
// phi->region->if_proj->ifnode->bool->cmp
|
||||||
|
BoolNode* bol = phi->in(0)->in(1)->in(0)->in(1)->as_Bool();
|
||||||
|
btest = bol->_test._test;
|
||||||
|
cmp = bol->in(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------repush_if_args--------------------------------
|
//-------------------------------repush_if_args--------------------------------
|
||||||
// Push arguments of an "if" bytecode back onto the stack by adjusting _sp.
|
// Push arguments of an "if" bytecode back onto the stack by adjusting _sp.
|
||||||
inline int Parse::repush_if_args() {
|
inline int Parse::repush_if_args() {
|
||||||
@ -1137,19 +1193,22 @@ void Parse::adjust_map_after_if(BoolTest::mask btest, Node* c, float prob,
|
|||||||
|
|
||||||
bool is_fallthrough = (path == successor_for_bci(iter().next_bci()));
|
bool is_fallthrough = (path == successor_for_bci(iter().next_bci()));
|
||||||
|
|
||||||
int cop = c->Opcode();
|
if (seems_never_taken(prob) && seems_stable_comparison(btest, c)) {
|
||||||
if (seems_never_taken(prob) && cop == Op_CmpP && btest == BoolTest::eq) {
|
|
||||||
// (An earlier version of do_if omitted '&& btest == BoolTest::eq'.)
|
|
||||||
//
|
|
||||||
// If this might possibly turn into an implicit null check,
|
// If this might possibly turn into an implicit null check,
|
||||||
// and the null has never yet been seen, we need to generate
|
// and the null has never yet been seen, we need to generate
|
||||||
// an uncommon trap, so as to recompile instead of suffering
|
// an uncommon trap, so as to recompile instead of suffering
|
||||||
// with very slow branches. (We'll get the slow branches if
|
// with very slow branches. (We'll get the slow branches if
|
||||||
// the program ever changes phase and starts seeing nulls here.)
|
// the program ever changes phase and starts seeing nulls here.)
|
||||||
//
|
//
|
||||||
// The tests we worry about are of the form (p == null).
|
// We do not inspect for a null constant, since a node may
|
||||||
// We do not simply inspect for a null constant, since a node may
|
|
||||||
// optimize to 'null' later on.
|
// optimize to 'null' later on.
|
||||||
|
//
|
||||||
|
// Null checks, and other tests which expect inequality,
|
||||||
|
// show btest == BoolTest::eq along the non-taken branch.
|
||||||
|
// On the other hand, type tests, must-be-null tests,
|
||||||
|
// and other tests which expect pointer equality,
|
||||||
|
// show btest == BoolTest::ne along the non-taken branch.
|
||||||
|
// We prune both types of branches if they look unused.
|
||||||
repush_if_args();
|
repush_if_args();
|
||||||
// We need to mark this branch as taken so that if we recompile we will
|
// We need to mark this branch as taken so that if we recompile we will
|
||||||
// see that it is possible. In the tiered system the interpreter doesn't
|
// see that it is possible. In the tiered system the interpreter doesn't
|
||||||
|
@ -119,7 +119,11 @@ void Parse::do_instanceof() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push the bool result back on stack
|
// Push the bool result back on stack
|
||||||
push( gen_instanceof( pop(), makecon(TypeKlassPtr::make(klass)) ) );
|
Node* res = gen_instanceof(peek(), makecon(TypeKlassPtr::make(klass)));
|
||||||
|
|
||||||
|
// Pop from stack AFTER gen_instanceof because it can uncommon trap.
|
||||||
|
pop();
|
||||||
|
push(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------array_store_check------------------------------
|
//------------------------------array_store_check------------------------------
|
||||||
|
@ -157,7 +157,7 @@ class StringConcat : public ResourceObj {
|
|||||||
Node* uct = _uncommon_traps.at(u);
|
Node* uct = _uncommon_traps.at(u);
|
||||||
|
|
||||||
// Build a new call using the jvms state of the allocate
|
// Build a new call using the jvms state of the allocate
|
||||||
address call_addr = SharedRuntime::uncommon_trap_blob()->instructions_begin();
|
address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
|
||||||
const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type();
|
const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type();
|
||||||
int size = call_type->domain()->cnt();
|
int size = call_type->domain()->cnt();
|
||||||
const TypePtr* no_memory_effects = NULL;
|
const TypePtr* no_memory_effects = NULL;
|
||||||
|
@ -314,7 +314,7 @@ void Type::Initialize_shared(Compile* current) {
|
|||||||
mreg2type[Op_RegL] = TypeLong::LONG;
|
mreg2type[Op_RegL] = TypeLong::LONG;
|
||||||
mreg2type[Op_RegFlags] = TypeInt::CC;
|
mreg2type[Op_RegFlags] = TypeInt::CC;
|
||||||
|
|
||||||
TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes());
|
TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), NULL /* current->env()->Object_klass() */, false, arrayOopDesc::length_offset_in_bytes());
|
||||||
|
|
||||||
TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot);
|
TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot);
|
||||||
|
|
||||||
@ -3683,12 +3683,10 @@ int TypeKlassPtr::hash(void) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------klass------------------------------------------
|
//----------------------compute_klass------------------------------------------
|
||||||
// Return the defining klass for this class
|
// Compute the defining klass for this class
|
||||||
ciKlass* TypeAryPtr::klass() const {
|
ciKlass* TypeAryPtr::compute_klass(DEBUG_ONLY(bool verify)) const {
|
||||||
if( _klass ) return _klass; // Return cached value, if possible
|
// Compute _klass based on element type.
|
||||||
|
|
||||||
// Oops, need to compute _klass and cache it
|
|
||||||
ciKlass* k_ary = NULL;
|
ciKlass* k_ary = NULL;
|
||||||
const TypeInstPtr *tinst;
|
const TypeInstPtr *tinst;
|
||||||
const TypeAryPtr *tary;
|
const TypeAryPtr *tary;
|
||||||
@ -3715,11 +3713,39 @@ ciKlass* TypeAryPtr::klass() const {
|
|||||||
} else {
|
} else {
|
||||||
// Cannot compute array klass directly from basic type,
|
// Cannot compute array klass directly from basic type,
|
||||||
// since subtypes of TypeInt all have basic type T_INT.
|
// since subtypes of TypeInt all have basic type T_INT.
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (verify && el->isa_int()) {
|
||||||
|
// Check simple cases when verifying klass.
|
||||||
|
BasicType bt = T_ILLEGAL;
|
||||||
|
if (el == TypeInt::BYTE) {
|
||||||
|
bt = T_BYTE;
|
||||||
|
} else if (el == TypeInt::SHORT) {
|
||||||
|
bt = T_SHORT;
|
||||||
|
} else if (el == TypeInt::CHAR) {
|
||||||
|
bt = T_CHAR;
|
||||||
|
} else if (el == TypeInt::INT) {
|
||||||
|
bt = T_INT;
|
||||||
|
} else {
|
||||||
|
return _klass; // just return specified klass
|
||||||
|
}
|
||||||
|
return ciTypeArrayKlass::make(bt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
assert(!el->isa_int(),
|
assert(!el->isa_int(),
|
||||||
"integral arrays must be pre-equipped with a class");
|
"integral arrays must be pre-equipped with a class");
|
||||||
// Compute array klass directly from basic type
|
// Compute array klass directly from basic type
|
||||||
k_ary = ciTypeArrayKlass::make(el->basic_type());
|
k_ary = ciTypeArrayKlass::make(el->basic_type());
|
||||||
}
|
}
|
||||||
|
return k_ary;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------klass------------------------------------------
|
||||||
|
// Return the defining klass for this class
|
||||||
|
ciKlass* TypeAryPtr::klass() const {
|
||||||
|
if( _klass ) return _klass; // Return cached value, if possible
|
||||||
|
|
||||||
|
// Oops, need to compute _klass and cache it
|
||||||
|
ciKlass* k_ary = compute_klass();
|
||||||
|
|
||||||
if( this != TypeAryPtr::OOPS ) {
|
if( this != TypeAryPtr::OOPS ) {
|
||||||
// The _klass field acts as a cache of the underlying
|
// The _klass field acts as a cache of the underlying
|
||||||
|
@ -831,11 +831,30 @@ class TypeInstPtr : public TypeOopPtr {
|
|||||||
//------------------------------TypeAryPtr-------------------------------------
|
//------------------------------TypeAryPtr-------------------------------------
|
||||||
// Class of Java array pointers
|
// Class of Java array pointers
|
||||||
class TypeAryPtr : public TypeOopPtr {
|
class TypeAryPtr : public TypeOopPtr {
|
||||||
TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id), _ary(ary) {};
|
TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id), _ary(ary) {
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (k != NULL) {
|
||||||
|
// Verify that specified klass and TypeAryPtr::klass() follow the same rules.
|
||||||
|
ciKlass* ck = compute_klass(true);
|
||||||
|
if (UseNewCode || k != ck) {
|
||||||
|
this->dump(); tty->cr();
|
||||||
|
tty->print(" k: ");
|
||||||
|
k->print(); tty->cr();
|
||||||
|
tty->print("ck: ");
|
||||||
|
if (ck != NULL) ck->print();
|
||||||
|
else tty->print("<NULL>");
|
||||||
|
tty->cr();
|
||||||
|
assert(false, "unexpected TypeAryPtr::_klass");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
virtual bool eq( const Type *t ) const;
|
virtual bool eq( const Type *t ) const;
|
||||||
virtual int hash() const; // Type specific hashing
|
virtual int hash() const; // Type specific hashing
|
||||||
const TypeAry *_ary; // Array we point into
|
const TypeAry *_ary; // Array we point into
|
||||||
|
|
||||||
|
ciKlass* compute_klass(DEBUG_ONLY(bool verify = false)) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Accessors
|
// Accessors
|
||||||
ciKlass* klass() const;
|
ciKlass* klass() const;
|
||||||
|
@ -114,7 +114,7 @@ void CodeBlobCollector::do_blob(CodeBlob* cb) {
|
|||||||
// check if this starting address has been seen already - the
|
// check if this starting address has been seen already - the
|
||||||
// assumption is that stubs are inserted into the list before the
|
// assumption is that stubs are inserted into the list before the
|
||||||
// enclosing BufferBlobs.
|
// enclosing BufferBlobs.
|
||||||
address addr = cb->instructions_begin();
|
address addr = cb->code_begin();
|
||||||
for (int i=0; i<_global_code_blobs->length(); i++) {
|
for (int i=0; i<_global_code_blobs->length(); i++) {
|
||||||
JvmtiCodeBlobDesc* scb = _global_code_blobs->at(i);
|
JvmtiCodeBlobDesc* scb = _global_code_blobs->at(i);
|
||||||
if (addr == scb->code_begin()) {
|
if (addr == scb->code_begin()) {
|
||||||
@ -123,8 +123,7 @@ void CodeBlobCollector::do_blob(CodeBlob* cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record the CodeBlob details as a JvmtiCodeBlobDesc
|
// record the CodeBlob details as a JvmtiCodeBlobDesc
|
||||||
JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(cb->name(), cb->instructions_begin(),
|
JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(cb->name(), cb->code_begin(), cb->code_end());
|
||||||
cb->instructions_end());
|
|
||||||
_global_code_blobs->append(scb);
|
_global_code_blobs->append(scb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,8 +687,8 @@ class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
|
|||||||
public:
|
public:
|
||||||
JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)
|
JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)
|
||||||
: JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
|
: JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
|
||||||
_code_data = nm->code_begin();
|
_code_data = nm->insts_begin();
|
||||||
_code_size = nm->code_size();
|
_code_size = nm->insts_size();
|
||||||
_compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.
|
_compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.
|
||||||
JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
|
JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
|
||||||
}
|
}
|
||||||
|
@ -113,8 +113,7 @@ void MethodHandles::generate_adapters() {
|
|||||||
_adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size);
|
_adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size);
|
||||||
if (_adapter_code == NULL)
|
if (_adapter_code == NULL)
|
||||||
vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
|
vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
|
||||||
CodeBuffer code(_adapter_code->instructions_begin(), _adapter_code->instructions_size());
|
CodeBuffer code(_adapter_code);
|
||||||
|
|
||||||
MethodHandlesAdapterGenerator g(&code);
|
MethodHandlesAdapterGenerator g(&code);
|
||||||
g.generate();
|
g.generate();
|
||||||
}
|
}
|
||||||
|
@ -1564,6 +1564,18 @@ bool Arguments::verify_interval(uintx val, uintx min,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Arguments::verify_min_value(intx val, intx min, const char* name) {
|
||||||
|
// Returns true if given value is greater than specified min threshold
|
||||||
|
// false, otherwise.
|
||||||
|
if (val >= min ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
|
"%s of " INTX_FORMAT " is invalid; must be greater than " INTX_FORMAT "\n",
|
||||||
|
name, val, min);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Arguments::verify_percentage(uintx value, const char* name) {
|
bool Arguments::verify_percentage(uintx value, const char* name) {
|
||||||
if (value <= 100) {
|
if (value <= 100) {
|
||||||
return true;
|
return true;
|
||||||
@ -1616,6 +1628,16 @@ bool Arguments::check_gc_consistency() {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check stack pages settings
|
||||||
|
bool Arguments::check_stack_pages()
|
||||||
|
{
|
||||||
|
bool status = true;
|
||||||
|
status = status && verify_min_value(StackYellowPages, 1, "StackYellowPages");
|
||||||
|
status = status && verify_min_value(StackRedPages, 1, "StackRedPages");
|
||||||
|
status = status && verify_min_value(StackShadowPages, 1, "StackShadowPages");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
// Check the consistency of vm_init_args
|
// Check the consistency of vm_init_args
|
||||||
bool Arguments::check_vm_args_consistency() {
|
bool Arguments::check_vm_args_consistency() {
|
||||||
// Method for adding checks for flag consistency.
|
// Method for adding checks for flag consistency.
|
||||||
@ -1728,6 +1750,7 @@ bool Arguments::check_vm_args_consistency() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = status && check_gc_consistency();
|
status = status && check_gc_consistency();
|
||||||
|
status = status && check_stack_pages();
|
||||||
|
|
||||||
if (_has_alloc_profile) {
|
if (_has_alloc_profile) {
|
||||||
if (UseParallelGC || UseParallelOldGC) {
|
if (UseParallelGC || UseParallelOldGC) {
|
||||||
|
@ -338,6 +338,7 @@ class Arguments : AllStatic {
|
|||||||
}
|
}
|
||||||
static bool verify_interval(uintx val, uintx min,
|
static bool verify_interval(uintx val, uintx min,
|
||||||
uintx max, const char* name);
|
uintx max, const char* name);
|
||||||
|
static bool verify_min_value(intx val, intx min, const char* name);
|
||||||
static bool verify_percentage(uintx value, const char* name);
|
static bool verify_percentage(uintx value, const char* name);
|
||||||
static void describe_range_error(ArgsRange errcode);
|
static void describe_range_error(ArgsRange errcode);
|
||||||
static ArgsRange check_memory_size(julong size, julong min_size);
|
static ArgsRange check_memory_size(julong size, julong min_size);
|
||||||
@ -400,6 +401,8 @@ class Arguments : AllStatic {
|
|||||||
static bool check_gc_consistency();
|
static bool check_gc_consistency();
|
||||||
// Check consistecy or otherwise of VM argument settings
|
// Check consistecy or otherwise of VM argument settings
|
||||||
static bool check_vm_args_consistency();
|
static bool check_vm_args_consistency();
|
||||||
|
// Check stack pages settings
|
||||||
|
static bool check_stack_pages();
|
||||||
// Used by os_solaris
|
// Used by os_solaris
|
||||||
static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized);
|
static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized);
|
||||||
|
|
||||||
|
@ -439,7 +439,7 @@ const char* StackWalkCompPolicy::shouldNotInline(methodHandle m) {
|
|||||||
if (!instanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized");
|
if (!instanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized");
|
||||||
if (m->is_native()) return (_msg = "native method");
|
if (m->is_native()) return (_msg = "native method");
|
||||||
nmethod* m_code = m->code();
|
nmethod* m_code = m->code();
|
||||||
if( m_code != NULL && m_code->instructions_size() > InlineSmallCode )
|
if (m_code != NULL && m_code->code_size() > InlineSmallCode)
|
||||||
return (_msg = "already compiled into a big method");
|
return (_msg = "already compiled into a big method");
|
||||||
|
|
||||||
// use frequency-based objections only for non-trivial methods
|
// use frequency-based objections only for non-trivial methods
|
||||||
|
@ -537,8 +537,8 @@ void frame::print_value_on(outputStream* st, JavaThread *thread) const {
|
|||||||
st->cr();
|
st->cr();
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (end == NULL) {
|
if (end == NULL) {
|
||||||
begin = _cb->instructions_begin();
|
begin = _cb->code_begin();
|
||||||
end = _cb->instructions_end();
|
end = _cb->code_end();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2476,6 +2476,9 @@ class CommandLineFlags {
|
|||||||
develop(bool, MonomorphicArrayCheck, true, \
|
develop(bool, MonomorphicArrayCheck, true, \
|
||||||
"Uncommon-trap array store checks that require full type check") \
|
"Uncommon-trap array store checks that require full type check") \
|
||||||
\
|
\
|
||||||
|
diagnostic(bool, ProfileDynamicTypes, true, \
|
||||||
|
"do extra type profiling and use it more aggressively") \
|
||||||
|
\
|
||||||
develop(bool, DelayCompilationDuringStartup, true, \
|
develop(bool, DelayCompilationDuringStartup, true, \
|
||||||
"Delay invoking the compiler until main application class is " \
|
"Delay invoking the compiler until main application class is " \
|
||||||
"loaded") \
|
"loaded") \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -33,7 +33,7 @@ void AbstractICache::initialize() {
|
|||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
BufferBlob* b = BufferBlob::create("flush_icache_stub", ICache::stub_size);
|
BufferBlob* b = BufferBlob::create("flush_icache_stub", ICache::stub_size);
|
||||||
CodeBuffer c(b->instructions_begin(), b->instructions_size());
|
CodeBuffer c(b);
|
||||||
|
|
||||||
ICacheStubGenerator g(&c);
|
ICacheStubGenerator g(&c);
|
||||||
g.generate_icache_flush(&_flush_icache_stub);
|
g.generate_icache_flush(&_flush_icache_stub);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -120,7 +120,7 @@ int InterpretedRFrame::cost() const {
|
|||||||
int CompiledRFrame::cost() const {
|
int CompiledRFrame::cost() const {
|
||||||
nmethod* nm = top_method()->code();
|
nmethod* nm = top_method()->code();
|
||||||
if (nm != NULL) {
|
if (nm != NULL) {
|
||||||
return nm->code_size();
|
return nm->insts_size();
|
||||||
} else {
|
} else {
|
||||||
return top_method()->code_size();
|
return top_method()->code_size();
|
||||||
}
|
}
|
||||||
|
@ -455,11 +455,11 @@ address SharedRuntime::get_poll_stub(address pc) {
|
|||||||
if (at_poll_return) {
|
if (at_poll_return) {
|
||||||
assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
|
assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
|
||||||
"polling page return stub not created yet");
|
"polling page return stub not created yet");
|
||||||
stub = SharedRuntime::polling_page_return_handler_blob()->instructions_begin();
|
stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
|
||||||
} else {
|
} else {
|
||||||
assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL,
|
assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL,
|
||||||
"polling page safepoint stub not created yet");
|
"polling page safepoint stub not created yet");
|
||||||
stub = SharedRuntime::polling_page_safepoint_handler_blob()->instructions_begin();
|
stub = SharedRuntime::polling_page_safepoint_handler_blob()->entry_point();
|
||||||
}
|
}
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if( TraceSafepoint ) {
|
if( TraceSafepoint ) {
|
||||||
@ -574,7 +574,7 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// found handling method => lookup exception handler
|
// found handling method => lookup exception handler
|
||||||
int catch_pco = ret_pc - nm->instructions_begin();
|
int catch_pco = ret_pc - nm->code_begin();
|
||||||
|
|
||||||
ExceptionHandlerTable table(nm);
|
ExceptionHandlerTable table(nm);
|
||||||
HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth);
|
HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth);
|
||||||
@ -607,7 +607,7 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nm->instructions_begin() + t->pco();
|
return nm->code_begin() + t->pco();
|
||||||
}
|
}
|
||||||
|
|
||||||
JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread))
|
JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread))
|
||||||
@ -2252,7 +2252,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
|
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
NOT_PRODUCT(int code_size);
|
NOT_PRODUCT(int insts_size);
|
||||||
AdapterBlob* B = NULL;
|
AdapterBlob* B = NULL;
|
||||||
AdapterHandlerEntry* entry = NULL;
|
AdapterHandlerEntry* entry = NULL;
|
||||||
AdapterFingerPrint* fingerprint = NULL;
|
AdapterFingerPrint* fingerprint = NULL;
|
||||||
@ -2305,7 +2305,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
|
|
||||||
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
|
CodeBuffer buffer(buf);
|
||||||
short buffer_locs[20];
|
short buffer_locs[20];
|
||||||
buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
|
buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
|
||||||
sizeof(buffer_locs)/sizeof(relocInfo));
|
sizeof(buffer_locs)/sizeof(relocInfo));
|
||||||
@ -2321,19 +2321,19 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (VerifyAdapterSharing) {
|
if (VerifyAdapterSharing) {
|
||||||
if (shared_entry != NULL) {
|
if (shared_entry != NULL) {
|
||||||
assert(shared_entry->compare_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt),
|
assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt),
|
||||||
"code must match");
|
"code must match");
|
||||||
// Release the one just created and return the original
|
// Release the one just created and return the original
|
||||||
_adapters->free_entry(entry);
|
_adapters->free_entry(entry);
|
||||||
return shared_entry;
|
return shared_entry;
|
||||||
} else {
|
} else {
|
||||||
entry->save_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt);
|
entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
B = AdapterBlob::create(&buffer);
|
B = AdapterBlob::create(&buffer);
|
||||||
NOT_PRODUCT(code_size = buffer.code_size());
|
NOT_PRODUCT(insts_size = buffer.insts_size());
|
||||||
}
|
}
|
||||||
if (B == NULL) {
|
if (B == NULL) {
|
||||||
// CodeCache is full, disable compilation
|
// CodeCache is full, disable compilation
|
||||||
@ -2343,16 +2343,16 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
CompileBroker::handle_full_code_cache();
|
CompileBroker::handle_full_code_cache();
|
||||||
return NULL; // Out of CodeCache space
|
return NULL; // Out of CodeCache space
|
||||||
}
|
}
|
||||||
entry->relocate(B->instructions_begin());
|
entry->relocate(B->content_begin());
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
// debugging suppport
|
// debugging suppport
|
||||||
if (PrintAdapterHandlers) {
|
if (PrintAdapterHandlers) {
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)",
|
tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)",
|
||||||
_adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"),
|
_adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"),
|
||||||
method->signature()->as_C_string(), fingerprint->as_string(), code_size );
|
method->signature()->as_C_string(), fingerprint->as_string(), insts_size );
|
||||||
tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
|
tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
|
||||||
Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + code_size);
|
Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + insts_size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2366,13 +2366,11 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
"%s(%s)@" PTR_FORMAT,
|
"%s(%s)@" PTR_FORMAT,
|
||||||
B->name(),
|
B->name(),
|
||||||
fingerprint->as_string(),
|
fingerprint->as_string(),
|
||||||
B->instructions_begin());
|
B->content_begin());
|
||||||
Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
|
Forte::register_stub(blob_id, B->content_begin(), B->content_end());
|
||||||
|
|
||||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||||
JvmtiExport::post_dynamic_code_generated(blob_id,
|
JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end());
|
||||||
B->instructions_begin(),
|
|
||||||
B->instructions_end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
@ -2456,7 +2454,7 @@ nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
|
|||||||
|
|
||||||
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
|
CodeBuffer buffer(buf);
|
||||||
double locs_buf[20];
|
double locs_buf[20];
|
||||||
buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
|
buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
|
||||||
MacroAssembler _masm(&buffer);
|
MacroAssembler _masm(&buffer);
|
||||||
@ -2540,7 +2538,7 @@ nmethod *AdapterHandlerLibrary::create_dtrace_nmethod(methodHandle method) {
|
|||||||
|
|
||||||
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
|
CodeBuffer buffer(buf);
|
||||||
// Need a few relocation entries
|
// Need a few relocation entries
|
||||||
double locs_buf[20];
|
double locs_buf[20];
|
||||||
buffer.insts()->initialize_shared_locs(
|
buffer.insts()->initialize_shared_locs(
|
||||||
|
@ -173,12 +173,12 @@ class SharedRuntime: AllStatic {
|
|||||||
|
|
||||||
static address get_ic_miss_stub() {
|
static address get_ic_miss_stub() {
|
||||||
assert(_ic_miss_blob!= NULL, "oops");
|
assert(_ic_miss_blob!= NULL, "oops");
|
||||||
return _ic_miss_blob->instructions_begin();
|
return _ic_miss_blob->entry_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
static address get_handle_wrong_method_stub() {
|
static address get_handle_wrong_method_stub() {
|
||||||
assert(_wrong_method_blob!= NULL, "oops");
|
assert(_wrong_method_blob!= NULL, "oops");
|
||||||
return _wrong_method_blob->instructions_begin();
|
return _wrong_method_blob->entry_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef COMPILER2
|
#ifdef COMPILER2
|
||||||
@ -188,15 +188,15 @@ class SharedRuntime: AllStatic {
|
|||||||
|
|
||||||
static address get_resolve_opt_virtual_call_stub(){
|
static address get_resolve_opt_virtual_call_stub(){
|
||||||
assert(_resolve_opt_virtual_call_blob != NULL, "oops");
|
assert(_resolve_opt_virtual_call_blob != NULL, "oops");
|
||||||
return _resolve_opt_virtual_call_blob->instructions_begin();
|
return _resolve_opt_virtual_call_blob->entry_point();
|
||||||
}
|
}
|
||||||
static address get_resolve_virtual_call_stub() {
|
static address get_resolve_virtual_call_stub() {
|
||||||
assert(_resolve_virtual_call_blob != NULL, "oops");
|
assert(_resolve_virtual_call_blob != NULL, "oops");
|
||||||
return _resolve_virtual_call_blob->instructions_begin();
|
return _resolve_virtual_call_blob->entry_point();
|
||||||
}
|
}
|
||||||
static address get_resolve_static_call_stub() {
|
static address get_resolve_static_call_stub() {
|
||||||
assert(_resolve_static_call_blob != NULL, "oops");
|
assert(_resolve_static_call_blob != NULL, "oops");
|
||||||
return _resolve_static_call_blob->instructions_begin();
|
return _resolve_static_call_blob->entry_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
static SafepointBlob* polling_page_return_handler_blob() { return _polling_page_return_handler_blob; }
|
static SafepointBlob* polling_page_return_handler_blob() { return _polling_page_return_handler_blob; }
|
||||||
@ -548,16 +548,17 @@ class SharedRuntime: AllStatic {
|
|||||||
// This library manages argument marshaling adapters and native wrappers.
|
// This library manages argument marshaling adapters and native wrappers.
|
||||||
// There are 2 flavors of adapters: I2C and C2I.
|
// There are 2 flavors of adapters: I2C and C2I.
|
||||||
//
|
//
|
||||||
// The I2C flavor takes a stock interpreted call setup, marshals the arguments
|
// The I2C flavor takes a stock interpreted call setup, marshals the
|
||||||
// for a Java-compiled call, and jumps to Rmethod-> code()->
|
// arguments for a Java-compiled call, and jumps to Rmethod-> code()->
|
||||||
// instructions_begin(). It is broken to call it without an nmethod assigned.
|
// code_begin(). It is broken to call it without an nmethod assigned.
|
||||||
// The usual behavior is to lift any register arguments up out of the stack
|
// The usual behavior is to lift any register arguments up out of the
|
||||||
// and possibly re-pack the extra arguments to be contigious. I2C adapters
|
// stack and possibly re-pack the extra arguments to be contigious.
|
||||||
// will save what the interpreter's stack pointer will be after arguments are
|
// I2C adapters will save what the interpreter's stack pointer will be
|
||||||
// popped, then adjust the interpreter's frame size to force alignment and
|
// after arguments are popped, then adjust the interpreter's frame
|
||||||
// possibly to repack the arguments. After re-packing, it jumps to the
|
// size to force alignment and possibly to repack the arguments.
|
||||||
// compiled code start. There are no safepoints in this adapter code and a GC
|
// After re-packing, it jumps to the compiled code start. There are
|
||||||
// cannot happen while marshaling is in progress.
|
// no safepoints in this adapter code and a GC cannot happen while
|
||||||
|
// marshaling is in progress.
|
||||||
//
|
//
|
||||||
// The C2I flavor takes a stock compiled call setup plus the target method in
|
// The C2I flavor takes a stock compiled call setup plus the target method in
|
||||||
// Rmethod, marshals the arguments for an interpreted call and jumps to
|
// Rmethod, marshals the arguments for an interpreted call and jumps to
|
||||||
|
@ -128,10 +128,9 @@ void StubRoutines::initialize1() {
|
|||||||
TraceTime timer("StubRoutines generation 1", TraceStartupTime);
|
TraceTime timer("StubRoutines generation 1", TraceStartupTime);
|
||||||
_code1 = BufferBlob::create("StubRoutines (1)", code_size1);
|
_code1 = BufferBlob::create("StubRoutines (1)", code_size1);
|
||||||
if (_code1 == NULL) {
|
if (_code1 == NULL) {
|
||||||
vm_exit_out_of_memory(code_size1,
|
vm_exit_out_of_memory(code_size1, "CodeCache: no room for StubRoutines (1)");
|
||||||
"CodeCache: no room for StubRoutines (1)");
|
|
||||||
}
|
}
|
||||||
CodeBuffer buffer(_code1->instructions_begin(), _code1->instructions_size());
|
CodeBuffer buffer(_code1);
|
||||||
StubGenerator_generate(&buffer, false);
|
StubGenerator_generate(&buffer, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,10 +180,9 @@ void StubRoutines::initialize2() {
|
|||||||
TraceTime timer("StubRoutines generation 2", TraceStartupTime);
|
TraceTime timer("StubRoutines generation 2", TraceStartupTime);
|
||||||
_code2 = BufferBlob::create("StubRoutines (2)", code_size2);
|
_code2 = BufferBlob::create("StubRoutines (2)", code_size2);
|
||||||
if (_code2 == NULL) {
|
if (_code2 == NULL) {
|
||||||
vm_exit_out_of_memory(code_size2,
|
vm_exit_out_of_memory(code_size2, "CodeCache: no room for StubRoutines (2)");
|
||||||
"CodeCache: no room for StubRoutines (2)");
|
|
||||||
}
|
}
|
||||||
CodeBuffer buffer(_code2->instructions_begin(), _code2->instructions_size());
|
CodeBuffer buffer(_code2);
|
||||||
StubGenerator_generate(&buffer, true);
|
StubGenerator_generate(&buffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +604,8 @@ static inline uint64_t cast_uint64_t(size_t x)
|
|||||||
nonstatic_field(CodeBlob, _size, int) \
|
nonstatic_field(CodeBlob, _size, int) \
|
||||||
nonstatic_field(CodeBlob, _header_size, int) \
|
nonstatic_field(CodeBlob, _header_size, int) \
|
||||||
nonstatic_field(CodeBlob, _relocation_size, int) \
|
nonstatic_field(CodeBlob, _relocation_size, int) \
|
||||||
nonstatic_field(CodeBlob, _instructions_offset, int) \
|
nonstatic_field(CodeBlob, _content_offset, int) \
|
||||||
|
nonstatic_field(CodeBlob, _code_offset, int) \
|
||||||
nonstatic_field(CodeBlob, _frame_complete_offset, int) \
|
nonstatic_field(CodeBlob, _frame_complete_offset, int) \
|
||||||
nonstatic_field(CodeBlob, _data_offset, int) \
|
nonstatic_field(CodeBlob, _data_offset, int) \
|
||||||
nonstatic_field(CodeBlob, _frame_size, int) \
|
nonstatic_field(CodeBlob, _frame_size, int) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user