diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers
index c1c80820a71..7ae48fec8e3 100644
--- a/jdk/make/mapfiles/libjava/mapfile-vers
+++ b/jdk/make/mapfiles/libjava/mapfile-vers
@@ -138,14 +138,9 @@ SUNWprivate_1.1 {
Java_java_lang_Double_longBitsToDouble;
Java_java_lang_Double_doubleToRawLongBits;
Java_java_lang_reflect_Proxy_defineClass0;
+ Java_java_lang_Shutdown_runAllFinalizers;
Java_java_lang_Float_intBitsToFloat;
Java_java_lang_Float_floatToRawIntBits;
- Java_java_lang_StackFrameInfo_fillInStackFrames;
- Java_java_lang_StackFrameInfo_setMethodInfo;
- Java_java_lang_StackStreamFactory_checkStackWalkModes;
- Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk;
- Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames;
- Java_java_lang_Shutdown_runAllFinalizers;
Java_java_lang_StrictMath_IEEEremainder;
Java_java_lang_StrictMath_acos;
Java_java_lang_StrictMath_asin;
diff --git a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java
deleted file mode 100644
index 1ef4a2aa041..00000000000
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import java.lang.StackWalker.StackFrame;
-import java.util.EnumSet;
-import java.util.Set;
-
-import static java.lang.StackWalker.ExtendedOption.LOCALS_AND_OPERANDS;
-
-/**
- * UNSUPPORTED This interface is intended to be package-private
- * or move to an internal package.
- *
- * {@code LiveStackFrame} represents a frame storing data and partial results.
- * Each frame has its own array of local variables (JVMS section 2.6.1),
- * its own operand stack (JVMS section 2.6.2) for a method invocation.
- *
- * @jvms 2.6 Frames
- */
-/* package-private */
-interface LiveStackFrame extends StackFrame {
- /**
- * Return the monitors held by this stack frame. This method returns
- * an empty array if no monitor is held by this stack frame.
- *
- * @return the monitors held by this stack frames
- */
- public Object[] getMonitors();
-
- /**
- * Gets the local variable array of this stack frame.
- *
- *
A single local variable can hold a value of type boolean, byte, char,
- * short, int, float, reference or returnAddress. A pair of local variables
- * can hold a value of type long or double. In other words,
- * a value of type long or type double occupies two consecutive local
- * variables. For a value of primitive type, the element in the
- * local variable array is an {@link PrimitiveValue} object;
- * otherwise, the element is an {@code Object}.
- *
- * @return the local variable array of this stack frame.
- */
- public Object[] getLocals();
-
- /**
- * Gets the operand stack of this stack frame.
- *
- *
- * The 0-th element of the returned array represents the top of the operand stack.
- * This method returns an empty array if the operand stack is empty.
- *
- *
Each entry on the operand stack can hold a value of any Java Virtual
- * Machine Type.
- * For a value of primitive type, the element in the returned array is
- * an {@link PrimitiveValue} object; otherwise, the element is the {@code Object}
- * on the operand stack.
- *
- * @return the operand stack of this stack frame.
- */
- public Object[] getStack();
-
- /**
- * UNSUPPORTED This interface is intended to be package-private
- * or move to an internal package.
- *
- * Represents a local variable or an entry on the operand whose value is
- * of primitive type.
- */
- public abstract class PrimitiveValue {
- /**
- * Returns the base type of this primitive value, one of
- * {@code B, D, C, F, I, J, S, Z}.
- *
- * @return Name of a base type
- * @jvms table 4.3-A
- */
- abstract char type();
-
- /**
- * Returns the boolean value if this primitive value is of type boolean.
- * @return the boolean value if this primitive value is of type boolean.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type boolean.
- */
- public boolean booleanValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the int value if this primitive value is of type int.
- * @return the int value if this primitive value is of type int.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type int.
- */
- public int intValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the long value if this primitive value is of type long.
- * @return the long value if this primitive value is of type long.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type long.
- */
- public long longValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the char value if this primitive value is of type char.
- * @return the char value if this primitive value is of type char.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type char.
- */
- public char charValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the byte value if this primitive value is of type byte.
- * @return the byte value if this primitive value is of type byte.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type byte.
- */
- public byte byteValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the short value if this primitive value is of type short.
- * @return the short value if this primitive value is of type short.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type short.
- */
- public short shortValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the float value if this primitive value is of type float.
- * @return the float value if this primitive value is of type float.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type float.
- */
- public float floatValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the double value if this primitive value is of type double.
- * @return the double value if this primitive value is of type double.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type double.
- */
- public double doubleValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
- }
-
-
- /**
- * Gets {@code StackWalker} that can get locals and operands.
- *
- * @throws SecurityException if the security manager is present and
- * denies access to {@code RuntimePermission("liveStackFrames")}
- */
- public static StackWalker getStackWalker() {
- return getStackWalker(EnumSet.noneOf(StackWalker.Option.class));
- }
-
- /**
- * Gets a {@code StackWalker} instance with the given options specifying
- * the stack frame information it can access, and which will traverse at most
- * the given {@code maxDepth} number of stack frames. If no option is
- * specified, this {@code StackWalker} obtains the method name and
- * the class name with all
- * {@linkplain StackWalker.Option#SHOW_HIDDEN_FRAMES hidden frames} skipped.
- * The returned {@code StackWalker} can get locals and operands.
- *
- * @param options stack walk {@link StackWalker.Option options}
- *
- * @throws SecurityException if the security manager is present and
- * it denies access to {@code RuntimePermission("liveStackFrames")}; or
- * or if the given {@code options} contains
- * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}
- * and it denies access to {@code StackFramePermission("retainClassReference")}.
- */
- public static StackWalker getStackWalker(Set options) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("liveStackFrames"));
- }
- return StackWalker.newInstance(options, LOCALS_AND_OPERANDS);
- }
-}
diff --git a/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java b/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java
deleted file mode 100644
index db8901ea731..00000000000
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import java.lang.StackWalker.Option;
-import java.util.EnumSet;
-import java.util.Set;
-
-import static java.lang.StackWalker.ExtendedOption.*;
-
-final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame {
- private static Object[] EMPTY_ARRAY = new Object[0];
-
- LiveStackFrameInfo(StackWalker walker) {
- super(walker);
- }
-
- // These fields are initialized by the VM if ExtendedOption.LOCALS_AND_OPERANDS is set
- private Object[] monitors = EMPTY_ARRAY;
- private Object[] locals = EMPTY_ARRAY;
- private Object[] operands = EMPTY_ARRAY;
-
- @Override
- public Object[] getMonitors() {
- return monitors;
- }
-
- @Override
- public Object[] getLocals() {
- return locals;
- }
-
- @Override
- public Object[] getStack() {
- return operands;
- }
-
- /*
- * Convert primitive value to {@code Primitive} object to represent
- * a local variable or an element on the operand stack of primitive type.
- */
- static PrimitiveValue asPrimitive(boolean value) {
- return new BooleanPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(int value) {
- return new IntPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(short value) {
- return new ShortPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(char value) {
- return new CharPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(byte value) {
- return new BytePrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(long value) {
- return new LongPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(float value) {
- return new FloatPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(double value) {
- return new DoublePrimitive(value);
- }
-
- private static class IntPrimitive extends PrimitiveValue {
- final int value;
- IntPrimitive(int value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'I';
- }
-
- @Override
- public int intValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class ShortPrimitive extends PrimitiveValue {
- final short value;
- ShortPrimitive(short value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'S';
- }
-
- @Override
- public short shortValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class BooleanPrimitive extends PrimitiveValue {
- final boolean value;
- BooleanPrimitive(boolean value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'Z';
- }
-
- @Override
- public boolean booleanValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class CharPrimitive extends PrimitiveValue {
- final char value;
- CharPrimitive(char value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'C';
- }
-
- @Override
- public char charValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class BytePrimitive extends PrimitiveValue {
- final byte value;
- BytePrimitive(byte value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'B';
- }
-
- @Override
- public byte byteValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class LongPrimitive extends PrimitiveValue {
- final long value;
- LongPrimitive(long value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'J';
- }
-
- @Override
- public long longValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class FloatPrimitive extends PrimitiveValue {
- final float value;
- FloatPrimitive(float value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'F';
- }
-
- @Override
- public float floatValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class DoublePrimitive extends PrimitiveValue {
- final double value;
- DoublePrimitive(double value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'D';
- }
-
- @Override
- public double doubleValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-}
diff --git a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java
deleted file mode 100644
index 5c7fbde5810..00000000000
--- a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import jdk.internal.misc.JavaLangInvokeAccess;
-import jdk.internal.misc.SharedSecrets;
-
-import static java.lang.StackWalker.Option.*;
-import java.lang.StackWalker.StackFrame;
-import java.util.Optional;
-import java.util.OptionalInt;
-
-class StackFrameInfo implements StackFrame {
- private final static JavaLangInvokeAccess jlInvokeAccess =
- SharedSecrets.getJavaLangInvokeAccess();
-
- // -XX:+MemberNameInStackFrame will initialize MemberName and all other fields;
- // otherwise, VM will set the hidden fields (injected by the VM).
- // -XX:+MemberNameInStackFrame is temporary to enable performance measurement
- //
- // Footprint improvement: MemberName::clazz and MemberName::name
- // can replace StackFrameInfo::declaringClass and StackFrameInfo::methodName
- // Currently VM sets StackFrameInfo::methodName instead of expanding MemberName::name
-
- final StackWalker walker;
- final Class> declaringClass;
- final Object memberName;
- final int bci;
-
- // methodName, fileName, and lineNumber will be lazily set by the VM
- // when first requested.
- private String methodName;
- private String fileName = null; // default for unavailable filename
- private int lineNumber = -1; // default for unavailable lineNumber
-
- /*
- * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
- * to use
- */
- StackFrameInfo(StackWalker walker) {
- this.walker = walker;
- this.declaringClass = null;
- this.bci = -1;
- this.memberName = jlInvokeAccess.newMemberName();
- }
-
- @Override
- public String getClassName() {
- return declaringClass.getName();
- }
-
- @Override
- public Class> getDeclaringClass() {
- walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
- return declaringClass;
- }
-
- // Call the VM to set methodName, lineNumber, and fileName
- private synchronized void ensureMethodInfoInitialized() {
- if (methodName == null) {
- setMethodInfo();
- }
- }
-
- @Override
- public String getMethodName() {
- ensureMethodInfoInitialized();
- return methodName;
- }
-
- @Override
- public Optional getFileName() {
- ensureMethodInfoInitialized();
- return fileName != null ? Optional.of(fileName) : Optional.empty();
- }
-
- @Override
- public OptionalInt getLineNumber() {
- ensureMethodInfoInitialized();
- return lineNumber > 0 ? OptionalInt.of(lineNumber) : OptionalInt.empty();
- }
-
- @Override
- public boolean isNativeMethod() {
- ensureMethodInfoInitialized();
- return lineNumber == -2;
- }
-
- @Override
- public String toString() {
- ensureMethodInfoInitialized();
- // similar format as StackTraceElement::toString
- if (isNativeMethod()) {
- return getClassName() + "." + getMethodName() + "(Native Method)";
- } else {
- // avoid allocating Optional objects
- return getClassName() + "." + getMethodName() +
- "(" + (fileName != null ? fileName : "Unknown Source") +
- (lineNumber > 0 ? ":" + lineNumber : " bci:" + bci) + ")";
- }
- }
-
- /**
- * Lazily initialize method name, file name, line number
- */
- private native void setMethodInfo();
-
- /**
- * Fill in source file name and line number of the given StackFrame array.
- */
- static native void fillInStackFrames(int startIndex,
- Object[] stackframes,
- int fromIndex, int toIndex);
-}
diff --git a/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java b/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java
deleted file mode 100644
index 58dcba496be..00000000000
--- a/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-/**
- * Permission to access {@link StackWalker.StackFrame}.
- *
- * @see java.lang.StackWalker.Option#RETAIN_CLASS_REFERENCE
- * @see StackWalker.StackFrame#getDeclaringClass()
- */
-public class StackFramePermission extends java.security.BasicPermission {
- private static final long serialVersionUID = 2841894854386706014L;
-
- /**
- * Creates a new {@code StackFramePermission} object.
- *
- * @param name Permission name. Must be "retainClassReference".
- *
- * @throws IllegalArgumentException if {@code name} is invalid.
- * @throws NullPointerException if {@code name} is {@code null}.
- */
- public StackFramePermission(String name) {
- super(name);
- if (!name.equals("retainClassReference")) {
- throw new IllegalArgumentException("name: " + name);
- }
- }
-}
diff --git a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java
deleted file mode 100644
index 7379184b643..00000000000
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import sun.misc.VM;
-
-import java.io.PrintStream;
-import java.lang.StackWalker.Option;
-import java.lang.StackWalker.StackFrame;
-
-import java.lang.annotation.Native;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-import static java.lang.StackStreamFactory.WalkerState.*;
-
-/**
- * StackStreamFactory class provides static factory methods
- * to get different kinds of stack walker/traverser.
- *
- * AbstractStackWalker provides the basic stack walking support
- * fetching stack frames from VM in batches.
- *
- * AbstractStackWalker subclass is specialized for a specific kind of stack traversal
- * to avoid overhead of Stream/Lambda
- * 1. Support traversing Stream
- * 2. StackWalker::getCallerClass
- * 3. Throwable::init and Throwable::getStackTrace
- * 4. AccessControlContext getting ProtectionDomain
- */
-final class StackStreamFactory {
- private StackStreamFactory() {}
-
- // Stack walk implementation classes to be excluded during stack walking
- // lazily add subclasses when they are loaded.
- private final static Set> stackWalkImplClasses = init();
-
- private static final int SMALL_BATCH = 8;
- private static final int BATCH_SIZE = 32;
- private static final int LARGE_BATCH_SIZE = 256;
- private static final int MIN_BATCH_SIZE = SMALL_BATCH;
-
- // These flags must match the values maintained in the VM
- @Native private static final int DEFAULT_MODE = 0x0;
- @Native private static final int FILL_CLASS_REFS_ONLY = 0x2;
- @Native private static final int FILTER_FILL_IN_STACKTRACE = 0x10;
- @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM
- @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100;
-
- /*
- * For Throwable to use StackWalker, set useNewThrowable to true.
- * Performance work and extensive testing is needed to replace the
- * VM built-in backtrace filled in Throwable with the StackWalker.
- */
- final static boolean useNewThrowable = getProperty("stackwalk.newThrowable", false);
- final static boolean isDebug = getProperty("stackwalk.debug", false);
-
- static StackFrameTraverser
- makeStackTraverser(StackWalker walker, Function super Stream, ? extends T> function)
- {
- if (walker.hasLocalsOperandsOption())
- return new LiveStackInfoTraverser(walker, function);
- else
- return new StackFrameTraverser(walker, function);
- }
-
- /**
- * Gets a stack stream to find caller class.
- */
- static CallerClassFinder makeCallerFinder(StackWalker walker) {
- return new CallerClassFinder(walker);
- }
-
- static boolean useStackTrace(Throwable t) {
- if (t instanceof VirtualMachineError)
- return false;
-
- return VM.isBooted() && StackStreamFactory.useNewThrowable;
- }
-
- /*
- * This should only be used by Throwable::.
- */
- static StackTrace makeStackTrace(Throwable ex) {
- return StackTrace.dump(ex);
- }
-
- /*
- * This creates StackTrace for Thread::dumpThread to use.
- */
- static StackTrace makeStackTrace() {
- return StackTrace.dump();
- }
-
- enum WalkerState {
- NEW, // the stream is new and stack walking has not started
- OPEN, // the stream is open when it is being traversed.
- CLOSED; // the stream is closed when the stack walking is done
- }
-
- static abstract class AbstractStackWalker {
- protected final StackWalker walker;
- protected final Thread thread;
- protected final int maxDepth;
- protected final long mode;
- protected int depth; // traversed stack depth
- protected FrameBuffer frameBuffer; // buffer for VM to fill in
- protected long anchor;
-
- // buffers to fill in stack frame information
- protected AbstractStackWalker(StackWalker walker, int mode) {
- this(walker, mode, Integer.MAX_VALUE);
- }
- protected AbstractStackWalker(StackWalker walker, int mode, int maxDepth) {
- this.thread = Thread.currentThread();
- this.mode = toStackWalkMode(walker, mode);
- this.walker = walker;
- this.maxDepth = maxDepth;
- this.depth = 0;
- }
-
- private int toStackWalkMode(StackWalker walker, int mode) {
- int newMode = mode;
- if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) &&
- !fillCallerClassOnly(newMode) /* don't show hidden frames for getCallerClass */)
- newMode |= SHOW_HIDDEN_FRAMES;
- if (walker.hasLocalsOperandsOption())
- newMode |= FILL_LIVE_STACK_FRAMES;
- return newMode;
- }
-
- private boolean fillCallerClassOnly(int mode) {
- return (mode|FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY;
- }
- /**
- * A callback method to consume the stack frames. This method is invoked
- * once stack walking begins (i.e. it is only invoked when walkFrames is called).
- *
- * Each specialized AbstractStackWalker subclass implements the consumeFrames method
- * to control the following:
- * 1. fetch the subsequent batches of stack frames
- * 2. reuse or expand the allocated buffers
- * 3. create specialized StackFrame objects
- *
- * @return the number of consumed frames
- */
- protected abstract T consumeFrames();
-
- /**
- * Initialize FrameBuffer. Subclass should implement this method to
- * create its custom frame buffers.
- */
- protected abstract void initFrameBuffer();
-
- /**
- * Returns the suggested next batch size.
- *
- * Subclass should override this method to change the batch size
- *
- * @param lastBatchFrameCount number of frames in the last batch; or zero
- * @return suggested batch size
- */
- protected abstract int batchSize(int lastBatchFrameCount);
-
- /*
- * Returns the next batch size, always >= minimum batch size (32)
- *
- * Subclass may override this method if the minimum batch size is different.
- */
- protected int getNextBatchSize() {
- int lastBatchSize = depth == 0 ? 0 : frameBuffer.curBatchFrameCount();
- int nextBatchSize = batchSize(lastBatchSize);
- if (isDebug) {
- System.err.println("last batch size = " + lastBatchSize +
- " next batch size = " + nextBatchSize);
- }
- return nextBatchSize >= MIN_BATCH_SIZE ? nextBatchSize : MIN_BATCH_SIZE;
- }
-
- /*
- * Checks if this stream is in the given state. Otherwise, throws IllegalStateException.
- *
- * VM also validates this stream if it's anchored for stack walking
- * when stack frames are fetched for each batch.
- */
- final void checkState(WalkerState state) {
- if (thread != Thread.currentThread()) {
- throw new IllegalStateException("Invalid thread walking this stack stream: " +
- Thread.currentThread().getName() + " " + thread.getName());
- }
- switch (state) {
- case NEW:
- if (this.anchor != 0) {
- throw new IllegalStateException("This stack stream is being reused.");
- }
- break;
- case OPEN:
- if (this.anchor <= 0) {
- throw new IllegalStateException("This stack stream is not valid for walking");
- }
- break;
- case CLOSED:
- if (this.anchor != -1L) {
- throw new IllegalStateException("This stack stream is not closed.");
- }
- }
- }
-
- /*
- * Close this stream. This stream becomes invalid to walk.
- */
- private void close() {
- this.anchor = -1L;
- }
-
- /*
- * Walks stack frames until {@link #consumeFrames} is done consuming
- * the frames it is interested in.
- */
- final T walk() {
- checkState(NEW);
- try {
- // VM will need to stablize the stack before walking. It will invoke
- // the AbstractStackWalker::doStackWalk method once it fetches the first batch.
- // the callback will be invoked within the scope of the callStackWalk frame.
- return beginStackWalk();
- } finally {
- close(); // done traversal; close the stream
- }
- }
-
- private boolean skipReflectionFrames() {
- return !walker.hasOption(Option.SHOW_REFLECT_FRAMES) &&
- !walker.hasOption(Option.SHOW_HIDDEN_FRAMES);
- }
-
- /*
- * Returns {@code Class} object at the current frame;
- * or {@code null} if no more frame. If advanceToNextBatch is true,
- * it will only fetch the next batch.
- */
- final Class> peekFrame() {
- while (frameBuffer.isActive() && depth < maxDepth) {
- if (frameBuffer.isEmpty()) {
- // fetch another batch of stack frames
- getNextBatch();
- } else {
- Class> c = frameBuffer.get();
- if (skipReflectionFrames() && isReflectionFrame(c)) {
- if (isDebug)
- System.err.println(" skip: frame " + frameBuffer.getIndex() + " " + c);
-
- frameBuffer.next();
- depth++;
- continue;
- } else {
- return c;
- }
- }
- }
- return null;
- }
-
- /*
- * This method is only invoked by VM.
- *
- * It will invoke the consumeFrames method to start the stack walking
- * with the first batch of stack frames. Each specialized AbstractStackWalker
- * subclass implements the consumeFrames method to control the following:
- * 1. fetch the subsequent batches of stack frames
- * 2. reuse or expand the allocated buffers
- * 3. create specialized StackFrame objects
- */
- private Object doStackWalk(long anchor, int skipFrames, int batchSize,
- int bufStartIndex, int bufEndIndex) {
- checkState(NEW);
-
- frameBuffer.check(skipFrames);
-
- if (isDebug) {
- System.err.format("doStackWalk: skip %d start %d end %d%n",
- skipFrames, bufStartIndex, bufEndIndex);
- }
-
- this.anchor = anchor; // set anchor for this bulk stack frame traversal
- frameBuffer.setBatch(bufStartIndex, bufEndIndex);
-
- // traverse all frames and perform the action on the stack frames, if specified
- return consumeFrames();
- }
-
- /*
- * Get next batch of stack frames.
- */
- private int getNextBatch() {
- int nextBatchSize = Math.min(maxDepth - depth, getNextBatchSize());
- if (!frameBuffer.isActive() || nextBatchSize <= 0) {
- if (isDebug) {
- System.out.format(" more stack walk done%n");
- }
- frameBuffer.freeze(); // stack walk done
- return 0;
- }
-
- return fetchStackFrames(nextBatchSize);
- }
-
- /*
- * This method traverses the next stack frame and returns the Class
- * invoking that stack frame.
- *
- * This method can only be called during the walk method. This is intended
- * to be used to walk the stack frames in one single invocation and
- * this stack stream will be invalidated once walk is done.
- *
- * @see #tryNextFrame
- */
- final Class> nextFrame() {
- if (!hasNext()) {
- return null;
- }
-
- Class> c = frameBuffer.next();
- depth++;
- return c;
- }
-
- /*
- * Returns true if there is next frame to be traversed.
- * This skips hidden frames unless this StackWalker has
- * {@link Option#SHOW_REFLECT_FRAMES}
- */
- final boolean hasNext() {
- return peekFrame() != null;
- }
-
- /**
- * Begin stack walking - pass the allocated arrays to the VM to fill in
- * stack frame information.
- *
- * VM first anchors the frame of the current thread. A traversable stream
- * on this thread's stack will be opened. The VM will fetch the first batch
- * of stack frames and call AbstractStackWalker::doStackWalk to invoke the
- * stack walking function on each stack frame.
- *
- * If all fetched stack frames are traversed, AbstractStackWalker::fetchStackFrames will
- * fetch the next batch of stack frames to continue.
- */
- private T beginStackWalk() {
- // initialize buffers for VM to fill the stack frame info
- initFrameBuffer();
-
- return callStackWalk(mode, 0,
- frameBuffer.curBatchFrameCount(),
- frameBuffer.startIndex(),
- frameBuffer.classes,
- frameBuffer.stackFrames);
- }
-
- /*
- * Fetches stack frames.
- *
- * @params batchSize number of elements of the frame buffers for this batch
- * @returns number of frames fetched in this batch
- */
- private int fetchStackFrames(int batchSize) {
- int startIndex = frameBuffer.startIndex();
- frameBuffer.resize(startIndex, batchSize);
-
- int endIndex = fetchStackFrames(mode, anchor, batchSize,
- startIndex,
- frameBuffer.classes,
- frameBuffer.stackFrames);
- if (isDebug) {
- System.out.format(" more stack walk requesting %d got %d to %d frames%n",
- batchSize, frameBuffer.startIndex(), endIndex);
- }
- int numFrames = endIndex - startIndex;
- if (numFrames == 0) {
- frameBuffer.freeze(); // done stack walking
- } else {
- frameBuffer.setBatch(startIndex, endIndex);
- }
- return numFrames;
- }
-
- /**
- * Begins stack walking. This method anchors this frame and invokes
- * AbstractStackWalker::doStackWalk after fetching the firt batch of stack frames.
- *
- * @param mode mode of stack walking
- * @param skipframes number of frames to be skipped before filling the frame buffer.
- * @param batchSize the batch size, max. number of elements to be filled in the frame buffers.
- * @param startIndex start index of the frame buffers to be filled.
- * @param classes Classes buffer of the stack frames
- * @param frames StackFrame buffer, or null
- * @return Result of AbstractStackWalker::doStackWalk
- */
- private native T callStackWalk(long mode, int skipframes,
- int batchSize, int startIndex,
- Class>[] classes,
- StackFrame[] frames);
-
- /**
- * Fetch the next batch of stack frames.
- *
- * @param mode mode of stack walking
- * @param anchor
- * @param batchSize the batch size, max. number of elements to be filled in the frame buffers.
- * @param startIndex start index of the frame buffers to be filled.
- * @param classes Classes buffer of the stack frames
- * @param frames StackFrame buffer, or null
- *
- * @return the end index to the frame buffers
- */
- private native int fetchStackFrames(long mode, long anchor,
- int batchSize, int startIndex,
- Class>[] classes,
- StackFrame[] frames);
-
-
- /*
- * Frame buffer
- *
- * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
- */
- class FrameBuffer {
- static final int START_POS = 2; // 0th and 1st elements are reserved
-
- // buffers for VM to fill stack frame info
- int currentBatchSize; // current batch size
- Class>[] classes; // caller class for fast path
-
- StackFrame[] stackFrames;
-
- int origin; // index to the current traversed stack frame
- int fence; // index to the last frame in the current batch
-
- FrameBuffer(int initialBatchSize) {
- if (initialBatchSize < MIN_BATCH_SIZE) {
- throw new IllegalArgumentException(initialBatchSize + " < minimum batch size: " + MIN_BATCH_SIZE);
- }
- this.origin = START_POS;
- this.fence = 0;
- this.currentBatchSize = initialBatchSize;
- this.classes = new Class>[currentBatchSize];
- }
-
- int curBatchFrameCount() {
- return currentBatchSize-START_POS;
- }
-
- /*
- * Tests if this frame buffer is empty. All frames are fetched.
- */
- final boolean isEmpty() {
- return origin >= fence || (origin == START_POS && fence == 0);
- }
-
- /*
- * Freezes this frame buffer. The stack stream source is done fetching.
- */
- final void freeze() {
- origin = 0;
- fence = 0;
- }
-
- /*
- * Tests if this frame buffer is active. It is inactive when
- * it is done for traversal. All stack frames have been traversed.
- */
- final boolean isActive() {
- return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
- }
-
- /**
- * Gets the class at the current frame and move to the next frame.
- */
- final Class> next() {
- if (isEmpty()) {
- throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
- }
- Class> c = classes[origin++];
- if (isDebug) {
- int index = origin-1;
- System.out.format(" next frame at %d: %s (origin %d fence %d)%n", index,
- Objects.toString(c), index, fence);
- }
- return c;
- }
-
- /**
- * Gets the class at the current frame.
- */
- final Class> get() {
- if (isEmpty()) {
- throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
- }
- return classes[origin];
- }
-
- /*
- * Returns the index of the current frame.
- */
- final int getIndex() {
- return origin;
- }
-
- /*
- * Set the start and end index of a new batch of stack frames that have
- * been filled in this frame buffer.
- */
- final void setBatch(int startIndex, int endIndex) {
- if (startIndex <= 0 || endIndex <= 0)
- throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
-
- this.origin = startIndex;
- this.fence = endIndex;
- if (depth == 0 && fence > 0) {
- // filter the frames due to the stack stream implementation
- for (int i = START_POS; i < fence; i++) {
- Class> c = classes[i];
- if (isDebug) System.err.format(" frame %d: %s%n", i, c);
- if (filterStackWalkImpl(c)) {
- origin++;
- } else {
- break;
- }
- }
- }
- }
-
- /*
- * Checks if the origin is the expected start index.
- */
- final void check(int skipFrames) {
- int index = skipFrames + START_POS;
- if (origin != index) {
- // stack walk must continue with the previous frame depth
- throw new IllegalStateException("origin " + origin + " != " + index);
- }
- }
-
- // ------ subclass may override the following methods -------
- /**
- * Resizes the buffers for VM to fill in the next batch of stack frames.
- * The next batch will start at the given startIndex with the maximum number
- * of elements.
- *
- *
Subclass may override this method to manage the allocated buffers.
- *
- * @param startIndex the start index for the first frame of the next batch to fill in.
- * @param elements the number of elements for the next batch to fill in.
- *
- */
- void resize(int startIndex, int elements) {
- if (!isActive())
- throw new IllegalStateException("inactive frame buffer can't be resized");
-
- int size = startIndex+elements;
- if (classes.length < size) {
- // copy the elements in classes array to the newly allocated one.
- // classes[0] is a Thread object
- Class>[] prev = classes;
- classes = new Class>[size];
- System.arraycopy(prev, 0, classes, 0, START_POS);
- }
- currentBatchSize = size;
- }
-
- /*
- * Returns the start index for this frame buffer is refilled.
- *
- * This implementation reuses the allocated buffer for the next batch
- * of stack frames. For subclass to retain the fetched stack frames,
- * it should override this method to return the index at which the frame
- * should be filled in for the next batch.
- */
- int startIndex() {
- return START_POS;
- }
-
- /**
- * Returns next StackFrame object in the current batch of stack frames
- */
- StackFrame nextStackFrame() {
- throw new InternalError("should not reach here");
- }
- }
- }
-
- /*
- * This StackFrameTraverser supports {@link Stream} traversal.
- *
- * This class implements Spliterator::forEachRemaining and Spliterator::tryAdvance.
- */
- static class StackFrameTraverser extends AbstractStackWalker
- implements Spliterator
- {
- static {
- stackWalkImplClasses.add(StackFrameTraverser.class);
- }
- private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.IMMUTABLE;
- class Buffer extends FrameBuffer {
- Buffer(int initialBatchSize) {
- super(initialBatchSize);
-
- this.stackFrames = new StackFrame[initialBatchSize];
- for (int i = START_POS; i < initialBatchSize; i++) {
- stackFrames[i] = new StackFrameInfo(walker);
- }
- }
-
- @Override
- void resize(int startIndex, int elements) {
- super.resize(startIndex, elements);
-
- int size = startIndex+elements;
- if (stackFrames.length < size) {
- stackFrames = new StackFrame[size];
- }
- for (int i = startIndex(); i < size; i++) {
- stackFrames[i] = new StackFrameInfo(walker);
- }
- }
-
- @Override
- StackFrame nextStackFrame() {
- if (isEmpty()) {
- throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
- }
-
- StackFrame frame = stackFrames[origin];
- origin++;
- return frame;
- }
- }
-
- final Function super Stream, ? extends T> function; // callback
-
- StackFrameTraverser(StackWalker walker,
- Function super Stream, ? extends T> function) {
- this(walker, function, DEFAULT_MODE);
- }
- StackFrameTraverser(StackWalker walker,
- Function super Stream, ? extends T> function,
- int mode) {
- super(walker, mode);
- this.function = function;
- }
-
- /**
- * Returns next StackFrame object in the current batch of stack frames;
- * or null if no more stack frame.
- */
- StackFrame nextStackFrame() {
- if (!hasNext()) {
- return null;
- }
-
- StackFrame frame = frameBuffer.nextStackFrame();
- depth++;
- return frame;
- }
-
- @Override
- protected T consumeFrames() {
- checkState(OPEN);
- Stream stream = StreamSupport.stream(this, false);
- if (function != null) {
- return function.apply(stream);
- } else
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void initFrameBuffer() {
- this.frameBuffer = new Buffer(getNextBatchSize());
- }
-
- @Override
- protected int batchSize(int lastBatchFrameCount) {
- if (lastBatchFrameCount == 0) {
- // First batch, use estimateDepth if not exceed the large batch size
- // and not too small
- int initialBatchSize = Math.max(walker.estimateDepth(), SMALL_BATCH);
- return Math.min(initialBatchSize, LARGE_BATCH_SIZE);
- } else {
- if (lastBatchFrameCount > BATCH_SIZE) {
- return lastBatchFrameCount;
- } else {
- return Math.min(lastBatchFrameCount*2, BATCH_SIZE);
- }
- }
- }
-
- // ------- Implementation of Spliterator
-
- @Override
- public Spliterator trySplit() {
- return null; // ordered stream and do not allow to split
- }
-
- @Override
- public long estimateSize() {
- return maxDepth;
- }
-
- @Override
- public int characteristics() {
- return CHARACTERISTICS;
- }
-
- @Override
- public void forEachRemaining(Consumer super StackFrame> action) {
- checkState(OPEN);
- for (int n = 0; n < maxDepth; n++) {
- StackFrame frame = nextStackFrame();
- if (frame == null) break;
-
- action.accept(frame);
- }
- }
-
- @Override
- public boolean tryAdvance(Consumer super StackFrame> action) {
- checkState(OPEN);
-
- int index = frameBuffer.getIndex();
- if (hasNext()) {
- StackFrame frame = nextStackFrame();
- action.accept(frame);
- if (isDebug) {
- System.err.println("tryAdvance: " + index + " " + frame);
- }
- return true;
- }
- if (isDebug) {
- System.err.println("tryAdvance: " + index + " NO element");
- }
- return false;
- }
- }
-
- /*
- * CallerClassFinder is specialized to return Class> for each stack frame.
- * StackFrame is not requested.
- */
- static class CallerClassFinder extends AbstractStackWalker {
- static {
- stackWalkImplClasses.add(CallerClassFinder.class);
- }
-
- private Class> caller;
-
- CallerClassFinder(StackWalker walker) {
- super(walker, FILL_CLASS_REFS_ONLY);
- }
-
- Class> findCaller() {
- walk();
- return caller;
- }
-
- @Override
- protected Integer consumeFrames() {
- checkState(OPEN);
- int n = 0;
- Class>[] frames = new Class>[2];
- // skip the API calling this getCallerClass method
- // 0: StackWalker::getCallerClass
- // 1: caller-sensitive method
- // 2: caller class
- while (n < 2 && (caller = nextFrame()) != null) {
- if (isMethodHandleFrame(caller)) continue;
- frames[n++] = caller;
- }
-
- if (frames[1] == null)
- throw new IllegalStateException("no caller frame");
- return n;
- }
-
- @Override
- protected void initFrameBuffer() {
- this.frameBuffer = new FrameBuffer(getNextBatchSize());
- }
-
- @Override
- protected int batchSize(int lastBatchFrameCount) {
- return MIN_BATCH_SIZE;
- }
-
- @Override
- protected int getNextBatchSize() {
- return MIN_BATCH_SIZE;
- }
- }
-
- /*
- * StackTrace caches all frames in the buffer. StackTraceElements are
- * created lazily when Throwable::getStackTrace is called.
- */
- static class StackTrace extends AbstractStackWalker {
- static {
- stackWalkImplClasses.add(StackTrace.class);
- }
-
- class GrowableBuffer extends FrameBuffer {
- GrowableBuffer(int initialBatchSize) {
- super(initialBatchSize);
-
- this.stackFrames = new StackFrame[initialBatchSize];
- for (int i = START_POS; i < initialBatchSize; i++) {
- stackFrames[i] = new StackFrameInfo(walker);
- }
- }
-
- /*
- * Returns the next index to fill
- */
- @Override
- int startIndex() {
- return origin;
- }
-
- /**
- * Initialize the buffers for VM to fill in the stack frame information.
- * The next batch will start at the given startIndex to
- * the length of the buffer.
- */
- @Override
- void resize(int startIndex, int elements) {
- // Expand the frame buffer.
- // Do not call super.resize that will reuse the filled elements
- // in this frame buffer
- int size = startIndex+elements;
- if (classes.length < size) {
- // resize the frame buffer
- classes = Arrays.copyOf(classes, size);
- stackFrames = Arrays.copyOf(stackFrames, size);
- }
- for (int i = startIndex; i < size; i++) {
- stackFrames[i] = new StackFrameInfo(walker);
- }
- currentBatchSize = size;
- }
-
- StackTraceElement get(int index) {
- return new StackTraceElement(classes[index].getName(), "unknown", null, -1);
- }
-
- /**
- * Returns an array of StackTraceElement for all stack frames cached in
- * this StackTrace object.
- *
- * This method is intended for Throwable::getOurStackTrace use only.
- */
- StackTraceElement[] toStackTraceElements() {
- int startIndex = START_POS;
- for (int i = startIndex; i < classes.length; i++) {
- if (classes[i] != null && filterStackWalkImpl(classes[i])) {
- startIndex++;
- } else {
- break;
- }
- }
-
- // VM fills in the method name, filename, line number info
- StackFrameInfo.fillInStackFrames(0, stackFrames, startIndex, startIndex + depth);
-
- StackTraceElement[] stes = new StackTraceElement[depth];
- for (int i = startIndex, j = 0; i < classes.length && j < depth; i++, j++) {
- if (isDebug) {
- System.err.println("StackFrame: " + i + " " + stackFrames[i]);
- }
- stes[j] = stackFrames[i].toStackTraceElement();
- }
- return stes;
- }
- }
-
- private static final int MAX_STACK_FRAMES = 1024;
- private static final StackWalker STACKTRACE_WALKER =
- StackWalker.newInstanceNoCheck(EnumSet.of(Option.SHOW_REFLECT_FRAMES));
-
- private StackTraceElement[] stes;
- static StackTrace dump() {
- return new StackTrace();
- }
-
- static StackTrace dump(Throwable ex) {
- return new StackTrace(ex);
- }
-
- private StackTrace() {
- this(STACKTRACE_WALKER, DEFAULT_MODE);
- }
-
- /*
- * Throwable::fillInStackTrace and of Throwable and subclasses
- * are filtered in the VM.
- */
- private StackTrace(Throwable ex) {
- this(STACKTRACE_WALKER, FILTER_FILL_IN_STACKTRACE); // skip Throwable::init frames
- if (isDebug) {
- System.err.println("dump stack for " + ex.getClass().getName());
- }
- }
-
- StackTrace(StackWalker walker, int mode) {
- super(walker, mode, MAX_STACK_FRAMES);
-
- // snapshot the stack trace
- walk();
- }
-
- @Override
- protected Integer consumeFrames() {
- // traverse all frames and perform the action on the stack frames, if specified
- int n = 0;
- while (n < maxDepth && nextFrame() != null) {
- n++;
- }
- return n;
- }
-
- @Override
- protected void initFrameBuffer() {
- this.frameBuffer = new GrowableBuffer(getNextBatchSize());
- }
-
- // TODO: implement better heuristic
- @Override
- protected int batchSize(int lastBatchFrameCount) {
- // chunk size of VM backtrace is 32
- return lastBatchFrameCount == 0 ? 32 : 32;
- }
-
- /**
- * Returns an array of StackTraceElement for all stack frames cached in
- * this StackTrace object.
- *
- * This method is intended for Throwable::getOurStackTrace use only.
- */
- synchronized StackTraceElement[] getStackTraceElements() {
- if (stes == null) {
- stes = ((GrowableBuffer) frameBuffer).toStackTraceElements();
- // release the frameBuffer memory
- frameBuffer = null;
- }
- return stes;
- }
-
- /*
- * Prints stack trace to the given PrintStream.
- *
- * Further implementation could skip creating StackTraceElement objects
- * print directly to the PrintStream.
- */
- void printStackTrace(PrintStream s) {
- StackTraceElement[] stes = getStackTraceElements();
- synchronized (s) {
- s.println("Stack trace");
- for (StackTraceElement traceElement : stes)
- s.println("\tat " + traceElement);
- }
- }
- }
-
- static class LiveStackInfoTraverser extends StackFrameTraverser {
- static {
- stackWalkImplClasses.add(LiveStackInfoTraverser.class);
- }
- // VM will fill in all method info and live stack info directly in StackFrameInfo
- class Buffer extends FrameBuffer {
- Buffer(int initialBatchSize) {
- super(initialBatchSize);
- this.stackFrames = new StackFrame[initialBatchSize];
- for (int i = START_POS; i < initialBatchSize; i++) {
- stackFrames[i] = new LiveStackFrameInfo(walker);
- }
- }
-
- @Override
- void resize(int startIndex, int elements) {
- super.resize(startIndex, elements);
- int size = startIndex + elements;
-
- if (stackFrames.length < size) {
- this.stackFrames = new StackFrame[size];
- }
-
- for (int i = startIndex(); i < size; i++) {
- stackFrames[i] = new LiveStackFrameInfo(walker);
- }
- }
-
- @Override
- StackFrame nextStackFrame() {
- if (isEmpty()) {
- throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
- }
-
- StackFrame frame = stackFrames[origin];
- origin++;
- return frame;
- }
- }
-
- LiveStackInfoTraverser(StackWalker walker,
- Function super Stream, ? extends T> function) {
- super(walker, function, DEFAULT_MODE);
- }
-
- @Override
- protected void initFrameBuffer() {
- this.frameBuffer = new Buffer(getNextBatchSize());
- }
- }
-
- private static native boolean checkStackWalkModes();
-
- // avoid loading other subclasses as they may not be used
- private static Set> init() {
- if (!checkStackWalkModes()) {
- throw new InternalError("StackWalker mode values do not match with JVM");
- }
-
- Set> classes = new HashSet<>();
- classes.add(StackWalker.class);
- classes.add(StackStreamFactory.class);
- classes.add(AbstractStackWalker.class);
- return classes;
- }
-
- private static boolean filterStackWalkImpl(Class> c) {
- return stackWalkImplClasses.contains(c) ||
- c.getName().startsWith("java.util.stream.");
- }
-
- // MethodHandle frames are not hidden and CallerClassFinder has
- // to filter them out
- private static boolean isMethodHandleFrame(Class> c) {
- return c.getName().startsWith("java.lang.invoke.");
- }
-
- private static boolean isReflectionFrame(Class> c) {
- if (c.getName().startsWith("sun.reflect") &&
- !sun.reflect.MethodAccessor.class.isAssignableFrom(c)) {
- throw new InternalError("Not sun.reflect.MethodAccessor: " + c.toString());
- }
- // ## should filter all @Hidden frames?
- return c == Method.class ||
- sun.reflect.MethodAccessor.class.isAssignableFrom(c) ||
- c.getName().startsWith("java.lang.invoke.LambdaForm");
- }
-
- private static boolean getProperty(String key, boolean value) {
- String s = AccessController.doPrivileged(new PrivilegedAction<>() {
- @Override
- public String run() {
- return System.getProperty(key);
- }
- });
- if (s != null) {
- return Boolean.valueOf(s);
- }
- return value;
- }
-}
diff --git a/jdk/src/java.base/share/classes/java/lang/StackWalker.java b/jdk/src/java.base/share/classes/java/lang/StackWalker.java
deleted file mode 100644
index ec5e581b7a6..00000000000
--- a/jdk/src/java.base/share/classes/java/lang/StackWalker.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang;
-
-import sun.reflect.CallerSensitive;
-
-import java.util.*;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-/**
- * A stack walker.
- *
- *
The {@link StackWalker#walk walk} method opens a sequential stream
- * of {@link StackFrame StackFrame}s for the current thread and then applies
- * the given function to walk the {@code StackFrame} stream.
- * The stream reports stack frame elements in order, from the top most frame
- * that represents the execution point at which the stack was generated to
- * the bottom most frame.
- * The {@code StackFrame} stream is closed when the {@code walk} method returns.
- * If an attempt is made to reuse the closed stream,
- * {@code IllegalStateException} will be thrown.
- *
- *
The {@linkplain Option stack walking options} of a
- * {@code StackWalker} determines the information of
- * {@link StackFrame StackFrame} objects to be returned.
- * By default, stack frames of the reflection API and implementation
- * classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden}
- * and {@code StackFrame}s have the class name and method name
- * available but not the {@link StackFrame#getDeclaringClass() Class reference}.
- *
- *
{@code StackWalker} is thread-safe. Multiple threads can share
- * a single {@code StackWalker} object to traverse its own stack.
- * A permission check is performed when a {@code StackWalker} is created,
- * according to the options it requests.
- * No further permission check is done at stack walking time.
- *
- * @apiNote
- * Examples
- *
- *
1. To find the first caller filtering a known list of implementation class:
- *
- *
- * Unless otherwise noted, passing a {@code null} argument to a
- * constructor or method in this {@code StackWalker} class
- * will cause a {@link NullPointerException NullPointerException}
- * to be thrown.
- *
- * @since 1.9
- */
-public final class StackWalker {
- /**
- * A {@code StackFrame} object represents a method invocation returned by
- * {@link StackWalker}.
- *
- *
The {@link #getDeclaringClass()} method may be unsupported as determined
- * by the {@linkplain Option stack walking options} of a {@linkplain
- * StackWalker stack walker}.
- *
- * @since 1.9
- * @jvms 2.6
- */
- public static interface StackFrame {
- /**
- * Gets the binary name
- * of the declaring class of the method represented by this stack frame.
- *
- * @return the binary name of the declaring class of the method
- * represented by this stack frame
- *
- * @jls 13.1 The Form of a Binary
- */
- public String getClassName();
-
- /**
- * Gets the name of the method represented by this stack frame.
- * @return the name of the method represented by this stack frame
- */
- public String getMethodName();
-
- /**
- * Gets the declaring {@code Class} for the method represented by
- * this stack frame.
- *
- * @return the declaring {@code Class} of the method represented by
- * this stack frame
- *
- * @throws UnsupportedOperationException if this {@code StackWalker}
- * is not configured with {@link Option#RETAIN_CLASS_REFERENCE
- * Option.RETAIN_CLASS_REFERENCE}.
- */
- public Class> getDeclaringClass();
-
- /**
- * Returns the name of the source file containing the execution point
- * represented by this stack frame. Generally, this corresponds
- * to the {@code SourceFile} attribute of the relevant {@code class}
- * file as defined by The Java Virtual Machine Specification.
- * In some systems, the name may refer to some source code unit
- * other than a file, such as an entry in a source repository.
- *
- * @return the name of the file containing the execution point
- * represented by this stack frame, or empty {@code Optional}
- * is unavailable.
- *
- * @jvms 4.7.10 The {@code SourceFile} Attribute
- */
- public Optional getFileName();
-
- /**
- * Returns the line number of the source line containing the execution
- * point represented by this stack frame. Generally, this is
- * derived from the {@code LineNumberTable} attribute of the relevant
- * {@code class} file as defined by The Java Virtual Machine
- * Specification.
- *
- * @return the line number of the source line containing the execution
- * point represented by this stack frame, or empty
- * {@code Optional} if this information is unavailable.
- *
- * @jvms 4.7.12 The {@code LineNumberTable} Attribute
- */
- public OptionalInt getLineNumber();
-
- /**
- * Returns {@code true} if the method containing the execution point
- * represented by this stack frame is a native method.
- *
- * @return {@code true} if the method containing the execution point
- * represented by this stack frame is a native method.
- */
- public boolean isNativeMethod();
-
- /**
- * Gets a {@code StackTraceElement} for this stack frame.
- *
- * @return {@code StackTraceElement} for this stack frame.
- *
- * */
- public default StackTraceElement toStackTraceElement() {
- int lineNumber = isNativeMethod() ? -2
- : getLineNumber().orElse(-1);
- return new StackTraceElement(getClassName(), getMethodName(),
- getFileName().orElse(null),
- lineNumber);
- }
- }
-
- /**
- * Stack walker option to configure the {@linkplain StackFrame stack frame}
- * information obtained by a {@code StackWalker}.
- *
- * @since 1.9
- */
- public enum Option {
- /**
- * Retains {@code Class} object in {@code StackFrame}s
- * walked by this {@code StackWalker}.
- *
- *
A {@code StackWalker} configured with this option will support
- * {@link StackWalker#getCallerClass()} and
- * {@link StackFrame#getDeclaringClass() StackFrame.getDeclaringClass()}.
- */
- RETAIN_CLASS_REFERENCE,
- /**
- * Shows all reflection frames.
- *
- *
By default, reflection frames are hidden. This includes the
- * {@link java.lang.reflect.Method#invoke} method
- * and the reflection implementation classes. A {@code StackWalker} with
- * this {@code SHOW_REFLECT_FRAMES} option will show all reflection frames.
- * The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
- * reflection frames and it will also show other hidden frames that
- * are implementation-specific.
- */
- SHOW_REFLECT_FRAMES,
- /**
- * Shows all hidden frames.
- *
- *
A Java Virtual Machine implementation may hide implementation
- * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
- * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
- * option will show all hidden frames (including reflection frames).
- */
- SHOW_HIDDEN_FRAMES;
- }
-
- enum ExtendedOption {
- /**
- * Obtain monitors, locals and operands.
- */
- LOCALS_AND_OPERANDS
- };
-
- static final EnumSet