Merge "Add DDM.Chunk extension command support."
am: e8a216345d
Change-Id: Ica0637765eaeb5c0360bf73b85d74beca9534987
diff --git a/make/data/jdwp/jdwp.spec b/make/data/jdwp/jdwp.spec
index aadede2..6c742b4 100644
--- a/make/data/jdwp/jdwp.spec
+++ b/make/data/jdwp/jdwp.spec
@@ -3027,6 +3027,28 @@
)
)
)
+(CommandSet DDM=-57
+ "The extension commands for ddms. Note that this is equivalent to the uint8_t value '199'."
+ (Command Chunk = 1
+ "Returns the output of processing a DDMS chunk with any registered handlers. Note: When an error occurs or no data is returned no error code will be set and the reply will be empty. This is for backwards compatibility."
+ (Out
+ (int ddms_type "The ddms type of the data that follows")
+ (Repeat ddms_data_length
+ (byte ddms_data "DDMS data to be processed by the handler registered for the given input_type.")
+ )
+ )
+ (Reply
+ (int ddms_type "The ddms type of the data that follows")
+ (Repeat ddms_data_length
+ (byte ddms_data "DDMS data returned from the handler")
+ )
+ )
+ (ErrorSet
+ (Error NOT_IMPLEMENTED "DDMS is not supported or set up.")
+ (Error VM_DEAD)
+ )
+ )
+)
(ConstantSet Error
(Constant NONE =0 "No error has occurred.")
(Constant INVALID_THREAD =10 "Passed thread is null, is not a valid thread or has exited.")
diff --git a/src/share/back/DDMImpl.c b/src/share/back/DDMImpl.c
new file mode 100644
index 0000000..80fe669
--- /dev/null
+++ b/src/share/back/DDMImpl.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1999, 2005, 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.
+ */
+
+#include "util.h"
+#include "DDMImpl.h"
+#include "inStream.h"
+#include "outStream.h"
+
+static jboolean
+chunk(PacketInputStream *in, PacketOutputStream *out)
+{
+ int i;
+ jint type_in;
+ jint type_out;
+ jint len_in;
+ jint len_out;
+ jbyte* data_in;
+ jbyte* data_out;
+ jvmtiError error;
+
+ type_in = inStream_readInt(in);
+ len_in = inStream_readInt(in);
+ data_in = inStream_readBytes(in, len_in, (jbyte*)jvmtiAllocate(len_in));
+
+ if (inStream_error(in)) {
+ return JNI_TRUE;
+ }
+
+ if (gdata->ddm_process_chunk == NULL) {
+ jvmtiDeallocate(data_in);
+ outStream_setError(out, JDWP_ERROR(NOT_IMPLEMENTED));
+ return JNI_TRUE;
+ }
+
+ LOG_JVMTI(("com.android.art.internal.ddm.process_chunk()"));
+ error = gdata->ddm_process_chunk(gdata->jvmti,
+ type_in,
+ len_in,
+ data_in,
+ &type_out,
+ &len_out,
+ &data_out);
+
+ jvmtiDeallocate(data_in);
+
+ if (error != JVMTI_ERROR_NONE) {
+ // For backwards-compatibility we do not actually return any error or any data at all
+ // here.
+ LOG_MISC(("Suppressing error from com.android.art.internal.ddm.process_chunk for backwards "
+ "compatibility. Error was %s (%d)", jvmtiErrorText(error), error));
+ return JNI_TRUE;
+ }
+
+ outStream_writeInt(out, type_out);
+ outStream_writeByteArray(out, len_out, data_out);
+ jvmtiDeallocate(data_out);
+
+ return JNI_TRUE;
+}
+
+void *DDM_Cmds[] = { (void *)1
+ ,(void *)chunk
+};
diff --git a/src/share/back/DDMImpl.h b/src/share/back/DDMImpl.h
new file mode 100644
index 0000000..4d92ef4
--- /dev/null
+++ b/src/share/back/DDMImpl.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+extern void *DDM_Cmds[];
+
diff --git a/src/share/back/debugDispatch.c b/src/share/back/debugDispatch.c
index e9e8c0e..f97fed7 100644
--- a/src/share/back/debugDispatch.c
+++ b/src/share/back/debugDispatch.c
@@ -42,6 +42,7 @@
#include "ArrayReferenceImpl.h"
#include "EventRequestImpl.h"
#include "StackFrameImpl.h"
+#include "DDMImpl.h"
static void **l1Array;
@@ -94,12 +95,15 @@
{
void **l2Array;
- if (cmdSet > JDWP_HIGHEST_COMMAND_SET) {
+ // ANDROID-CHANGED: DDMS has cmdSet -57 (199u). Check for this one specifically.
+ if (cmdSet == JDWP_COMMAND_SET(DDM)) {
+ l2Array = (void **)DDM_Cmds;
+ } else if (cmdSet > JDWP_HIGHEST_COMMAND_SET || cmdSet < 0) {
return NULL;
+ } else {
+ l2Array = (void **)l1Array[cmdSet];
}
- l2Array = (void **)l1Array[cmdSet];
-
/*
* If there is no such CommandSet or the Command
* is greater than the nummber of commands (the first
diff --git a/src/share/back/debugInit.c b/src/share/back/debugInit.c
index 955e9eb..474c197 100644
--- a/src/share/back/debugInit.c
+++ b/src/share/back/debugInit.c
@@ -194,6 +194,44 @@
minor_runtime >= minor_compiletime;
}
+// ANDROID-CHANGED: Function to get and set the com.android.art.internal.ddm.process_chunk extension
+// function. This returns JNI_ERR if something went wrong with searching. If the extension is not
+// found we return JNI_OK and don't bother updating the gdata pointer.
+static jint find_ddm_process_chunk()
+{
+ jvmtiError error;
+ jvmtiExtensionFunctionInfo* extension_info;
+ jint num_extensions;
+ jboolean found;
+ int i;
+ int j;
+
+ found = JNI_FALSE;
+ error = JVMTI_FUNC_PTR(gdata->jvmti,GetExtensionFunctions)
+ (gdata->jvmti, &num_extensions, &extension_info);
+ if (error != JVMTI_ERROR_NONE) {
+ ERROR_MESSAGE(("JDWP Unable to get jvmti extension functions: %s(%d)",
+ jvmtiErrorText(error), error));
+ return JNI_ERR;
+ }
+ // We iterate through every extension function even once we found the one we want in order to
+ // clean them all up as we go.
+ for (i = 0; i < num_extensions; i++) {
+ if (strcmp("com.android.art.internal.ddm.process_chunk", extension_info[i].id) == 0) {
+ gdata->ddm_process_chunk = (DdmProcessChunk) extension_info[i].func;
+ }
+ jvmtiDeallocate(extension_info[i].id);
+ jvmtiDeallocate(extension_info[i].short_description);
+ for (j = 0; j < extension_info[i].param_count; j++) {
+ jvmtiDeallocate(extension_info[i].params[j].name);
+ }
+ jvmtiDeallocate(extension_info[i].params);
+ jvmtiDeallocate(extension_info[i].errors);
+ }
+ jvmtiDeallocate(extension_info);
+ return JNI_OK;
+}
+
/* OnLoad startup:
* Returning JNI_ERR will cause the java_g VM to core dump, be careful.
*/
@@ -400,6 +438,13 @@
return JNI_ERR;
}
+ // ANDROID-CHANGED: Find com.android.art.internal.ddm.process_chunk function if it exists.
+ if (find_ddm_process_chunk() != JNI_OK) {
+ ERROR_MESSAGE(("Fatal error while attempting to find the "
+ "com.android.art.internal.ddm.process_chunk extension function"));
+ return JNI_ERR;
+ }
+
LOG_MISC(("OnLoad: DONE"));
return JNI_OK;
}
diff --git a/src/share/back/util.h b/src/share/back/util.h
index 0f9aa1c..3b67bfa 100644
--- a/src/share/back/util.h
+++ b/src/share/back/util.h
@@ -74,6 +74,15 @@
typedef jint FrameNumber;
+// ANDROID-CHANGED: support for DDMS extension apis.
+typedef jvmtiError (*DdmProcessChunk)(jvmtiEnv* jvmti,
+ jint type_in,
+ jint length_in,
+ const jbyte* data_in,
+ jint* type_out,
+ jint* length_out,
+ jbyte** data_out);
+
typedef struct {
jvmtiEnv *jvmti;
JavaVM *jvm;
@@ -136,6 +145,9 @@
/* Indication that the agent has been loaded */
jboolean isLoaded;
+ /* ANDROID-CHANGED: com.android.art.internal.ddm.process_chunk extension function */
+ DdmProcessChunk ddm_process_chunk;
+
} BackendGlobalData;
extern BackendGlobalData * gdata;