OSDN Git Service

am 486ac3c0: Removing inaccurate and unmaintained docs.
authorDan Bornstein <danfuzz@android.com>
Thu, 24 Mar 2011 00:53:04 +0000 (17:53 -0700)
committerAndroid Git Automerger <android-git-automerger@android.com>
Thu, 24 Mar 2011 00:53:04 +0000 (17:53 -0700)
* commit '486ac3c0a90b05be5af4b82801ef325e83241057':
  Removing inaccurate and unmaintained docs.

28 files changed:
dexdump/NOTICE [new file with mode: 0644]
docs/heap-profiling.html
docs/porting-guide.html
dx/NOTICE [new file with mode: 0644]
libdex/CmdUtils.c
libdex/DexProto.c
libdex/DexProto.h
libdex/ZipArchive.c
libnativehelper/JNIHelp.c
libnativehelper/include/nativehelper/JNIHelp.h
tests/011-array-copy/expected.txt
tests/011-array-copy/src/Main.java
vm/Android.mk
vm/CheckJni.c
vm/DalvikVersion.h
vm/JarFile.c
vm/Jni.c
vm/mterp/cstubs/entry.c
vm/mterp/out/InterpAsm-x86-atom.S
vm/mterp/out/InterpC-allstubs.c
vm/native/dalvik_system_DexFile.c
vm/native/dalvik_system_VMDebug.c
vm/native/dalvik_system_Zygote.c
vm/native/java_lang_Class.c
vm/native/java_lang_System.c
vm/oo/Object.h
vm/reflect/Reflect.c
vm/reflect/Reflect.h

diff --git a/dexdump/NOTICE b/dexdump/NOTICE
new file mode 100644 (file)
index 0000000..c5b1efa
--- /dev/null
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
index dfb3cd1..3707377 100644 (file)
@@ -177,7 +177,7 @@ The <code>kill -10</code> (<code>SIGUSR1</code>) method of generating heap
 dumps has been removed from the VM.
 </p>
 
-<h3>Android x.y ("Honeycomb")</h3>
+<h3>Android 3.0 ("Honeycomb")</h3>
 <p>
 A new command-line tool has been added:
 </p>
index 3e33d13..d1a1ea3 100644 (file)
@@ -26,8 +26,7 @@ build system is assumed.
 <p>
 The native code in the core libraries (chiefly <code>libcore</code>,
 but also <code>dalvik/vm/native</code>) is written in C/C++ and is expected
-to work without modification in a Linux environment.  Much of the code
-comes directly from the Apache Harmony project.
+to work without modification in a Linux environment.
 </p><p>
 The core libraries pull in code from many other projects, including
 OpenSSL, zlib, and ICU.  These will also need to be ported before the VM
@@ -165,6 +164,9 @@ source files.
 <li>Make sure <code>dalvik/vm/Android.mk</code> will find the files for
 your architecture.  If <code>$(TARGET_ARCH)</code> is configured this
 will happen automatically.
+<li>Disable the Dalvik JIT.  You can do this in the general device
+configuration, or by editing the initialization of WITH_JIT in
+<code>dalvik/vm/Dvm.mk</code> to always be <code>false</code>.
 </ol>
 </p><p>
 You now have the basic framework in place.  Whenever you make a change, you
@@ -178,7 +180,7 @@ of the files in <code>dalvik/vm/mterp/out</code> by executing
 in assembly.
 <li>In the <code>dalvik</code> directory, regenerate the
 <code>libdvm.so</code> library with <code>mm</code>.  You can also use
-<code>make libdvm</code> from the top of the tree.
+<code>mmm dalvik/vm</code> from the top of the tree.
 </ol>
 </p><p>
 This will leave you with an updated libdvm.so, which can be pushed out to
@@ -242,7 +244,7 @@ for examples.
 <h3>Replacing Stubs</h3>
 
 <p>
-There are roughly 230 Dalvik opcodes, including some that are inserted by
+There are roughly 250 Dalvik opcodes, including some that are inserted by
 <a href="dexopt.html">dexopt</a> and aren't described in the
 <a href="dalvik-bytecode.html">Dalvik bytecode</a> documentation.  Each
 one must perform the appropriate actions, fetch the next opcode, and
@@ -349,6 +351,22 @@ debugger or toggle profiling.  (A future test suite may include some
 tests for this.)
 </p>
 
+
+<h2>Other Performance Issues</h2>
+
+<p>
+The <code>System.arraycopy()</code> function is heavily used.  The
+implementation relies on the bionic C library to provide a fast,
+platform-optimized data copy function for arrays with elements wider
+than one byte.  If you're not using bionic, or your platform does not
+have an implementation of this method, Dalvik will use correct but
+sub-optimal algorithms instead.  For best performance you will want
+to provide your own version.
+</p><p>
+See the comments in <code>dalvik/vm/native/java_lang_System.c</code>
+for details.
+</p>
+
 <p>
 <address>Copyright &copy; 2009 The Android Open Source Project</address>
 
diff --git a/dx/NOTICE b/dx/NOTICE
new file mode 100644 (file)
index 0000000..c5b1efa
--- /dev/null
+++ b/dx/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
index e81d80f..6a054c8 100644 (file)
@@ -25,6 +25,9 @@
 #include <fcntl.h>
 #include <errno.h>
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
 
 /*
  * Extract "classes.dex" from archive file.
@@ -170,7 +173,7 @@ UnzipToFileResult dexOpenAndMap(const char* fileName, const char* tempFileName,
     /*
      * Pop open the (presumed) DEX file.
      */
-    fd = open(fileName, O_RDONLY);
+    fd = open(fileName, O_RDONLY | O_BINARY);
     if (fd < 0) {
         if (!quiet) {
             fprintf(stderr, "ERROR: unable to open '%s': %s\n",
index b5574dc..25ab400 100644 (file)
@@ -33,7 +33,7 @@
  * Make sure that the given cache can hold a string of the given length,
  * including the final '\0' byte.
  */
-static void dexStringCacheAlloc(DexStringCache* pCache, size_t length) {
+void dexStringCacheAlloc(DexStringCache* pCache, size_t length) {
     if (pCache->allocatedSize != 0) {
         if (pCache->allocatedSize >= length) {
             return;
@@ -122,19 +122,14 @@ static inline const DexProtoId* getProtoId(const DexProto* pProto) {
     return dexGetProtoId(pProto->dexFile, pProto->protoIdx);
 }
 
-/*
- * Get the short-form method descriptor for the given prototype. The
- * prototype must be protoIdx-based.
- */
+/* (documented in header file) */
 const char* dexProtoGetShorty(const DexProto* pProto) {
     const DexProtoId* protoId = getProtoId(pProto);
 
     return dexStringById(pProto->dexFile, protoId->shortyIdx);
 }
 
-/*
- * Get the full method descriptor for the given prototype.
- */
+/* (documented in header file) */
 const char* dexProtoGetMethodDescriptor(const DexProto* pProto,
         DexStringCache* pCache) {
     const DexFile* dexFile = pProto->dexFile;
@@ -169,10 +164,7 @@ const char* dexProtoGetMethodDescriptor(const DexProto* pProto,
     return pCache->value;
 }
 
-/*
- * Get a copy of the descriptor string associated with the given prototype.
- * The returned pointer must be free()ed by the caller.
- */
+/* (documented in header file) */
 char* dexProtoCopyMethodDescriptor(const DexProto* pProto) {
     DexStringCache cache;
 
@@ -181,11 +173,7 @@ char* dexProtoCopyMethodDescriptor(const DexProto* pProto) {
             dexProtoGetMethodDescriptor(pProto, &cache));
 }
 
-/*
- * Get the parameter descriptors for the given prototype. This is the
- * concatenation of all the descriptors for all the parameters, in
- * order, with no other adornment.
- */
+/* (documented in header file) */
 const char* dexProtoGetParameterDescriptors(const DexProto* pProto,
         DexStringCache* pCache) {
     DexParameterIterator iterator;
@@ -220,17 +208,13 @@ const char* dexProtoGetParameterDescriptors(const DexProto* pProto,
     return pCache->value;
 }
 
-/*
- * Get the type descriptor for the return type of the given prototype.
- */
+/* (documented in header file) */
 const char* dexProtoGetReturnType(const DexProto* pProto) {
     const DexProtoId* protoId = getProtoId(pProto);
     return dexStringByTypeIdx(pProto->dexFile, protoId->returnTypeIdx);
 }
 
-/*
- * Get the parameter count of the given prototype.
- */
+/* (documented in header file) */
 size_t dexProtoGetParameterCount(const DexProto* pProto) {
     const DexProtoId* protoId = getProtoId(pProto);
     const DexTypeList* typeList =
@@ -238,12 +222,7 @@ size_t dexProtoGetParameterCount(const DexProto* pProto) {
     return (typeList == NULL) ? 0 : typeList->size;
 }
 
-/*
- * Compute the number of parameter words (u4 units) required by the
- * given prototype. For example, if the method takes (int, long) and
- * returns double, this would return 3 (one for the int, two for the
- * long, and the return type isn't relevant).
- */
+/* (documented in header file) */
 int dexProtoComputeArgsSize(const DexProto* pProto) {
     const char* shorty = dexProtoGetShorty(pProto);
     int count = 0;
@@ -335,24 +314,12 @@ static int protoCompare(const DexProto* pProto1, const DexProto* pProto2,
     }
 }
 
-/*
- * Compare the two prototypes. The two prototypes are compared
- * with the return type as the major order, then the first arguments,
- * then second, etc. If two prototypes are identical except that one
- * has extra arguments, then the shorter argument is considered the
- * earlier one in sort order (similar to strcmp()).
- */
+/* (documented in header file) */
 int dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2) {
     return protoCompare(pProto1, pProto2, true);
 }
 
-/*
- * Compare the two prototypes. The two prototypes are compared
- * with the first argument as the major order, then second, etc. If two
- * prototypes are identical except that one has extra arguments, then the
- * shorter argument is considered the earlier one in sort order (similar
- * to strcmp()).
- */
+/* (documented in header file) */
 int dexProtoCompareParameters(const DexProto* pProto1, const DexProto* pProto2){
     return protoCompare(pProto1, pProto2, false);
 }
@@ -404,34 +371,28 @@ static const char* methodDescriptorNextType(const char* descriptor) {
 }
 
 /*
- * Compare a prototype and a string method descriptor. The comparison
- * is done as if the descriptor were converted to a prototype and compared
- * with dexProtoCompare().
+ * Common implementation for dexProtoCompareToDescriptor() and
+ * dexProtoCompareToParameterDescriptors(). The descriptor argument
+ * can be either a full method descriptor (with parens and a return
+ * type) or an unadorned concatenation of types (e.g. a list of
+ * argument types).
  */
-int dexProtoCompareToDescriptor(const DexProto* proto,
-        const char* descriptor) {
-    // First compare the return types.
-
-    int result = strcmp(dexProtoGetReturnType(proto),
-            methodDescriptorReturnType(descriptor));
-
-    if (result != 0) {
-        return result;
-    }
-
-    // The return types match, so we have to check arguments.
-
+static int protoCompareToParameterDescriptors(const DexProto* proto,
+        const char* descriptor, bool expectParens) {
+    char expectedEndChar = expectParens ? ')' : '\0';
     DexParameterIterator iterator;
     dexParameterIteratorInit(&iterator, proto);
 
-    // Skip the '('.
-    assert (*descriptor == '(');
-    descriptor++;
+    if (expectParens) {
+        // Skip the '('.
+        assert (*descriptor == '(');
+        descriptor++;
+    }
 
     for (;;) {
         const char* protoDesc = dexParameterIteratorNextDescriptor(&iterator);
 
-        if (*descriptor == ')') {
+        if (*descriptor == expectedEndChar) {
             // It's the end of the descriptor string.
             if (protoDesc == NULL) {
                 // It's also the end of the prototype's arguments.
@@ -453,6 +414,7 @@ int dexProtoCompareToDescriptor(const DexProto* proto,
         // Both prototype and descriptor have arguments. Compare them.
 
         const char* nextDesc = methodDescriptorNextType(descriptor);
+        assert(nextDesc != NULL);
 
         for (;;) {
             char c1 = *(protoDesc++);
@@ -477,6 +439,34 @@ int dexProtoCompareToDescriptor(const DexProto* proto,
     }
 }
 
+/* (documented in header file) */
+int dexProtoCompareToDescriptor(const DexProto* proto,
+        const char* descriptor) {
+    // First compare the return types.
+
+    const char *returnType = methodDescriptorReturnType(descriptor);
+    assert(returnType != NULL);
+
+    int result = strcmp(dexProtoGetReturnType(proto), returnType);
+
+    if (result != 0) {
+        return result;
+    }
+
+    // The return types match, so we have to check arguments.
+    return protoCompareToParameterDescriptors(proto, descriptor, true);
+}
+
+/* (documented in header file) */
+int dexProtoCompareToParameterDescriptors(const DexProto* proto,
+        const char* descriptors) {
+    return protoCompareToParameterDescriptors(proto, descriptors, false);
+}
+
+
+
+
+
 
 /*
  * ===========================================================================
index 1ef577b..50d4bf3 100644 (file)
@@ -37,6 +37,12 @@ typedef struct DexStringCache {
 } DexStringCache;
 
 /*
+ * Make sure that the given cache can hold a string of the given length,
+ * including the final '\0' byte.
+ */
+void dexStringCacheAlloc(DexStringCache* pCache, size_t length);
+
+/*
  * Initialize the given DexStringCache. Use this function before passing
  * one into any other function.
  */
@@ -165,13 +171,14 @@ int dexProtoComputeArgsSize(const DexProto* pProto);
 int dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2);
 
 /*
- * Compare the two prototypes. The two prototypes are compared
- * with the first argument as the major order, then second, etc. If two
- * prototypes are identical except that one has extra arguments, then the
- * shorter argument is considered the earlier one in sort order (similar
- * to strcmp()).
+ * Compare the two prototypes, ignoring return type. The two
+ * prototypes are compared with the first argument as the major order,
+ * then second, etc. If two prototypes are identical except that one
+ * has extra arguments, then the shorter argument is considered the
+ * earlier one in sort order (similar to strcmp()).
  */
-int dexProtoCompareParameters(const DexProto* pProto1, const DexProto* pProto2);
+int dexProtoCompareParameters(const DexProto* pProto1,
+        const DexProto* pProto2);
 
 /*
  * Compare a prototype and a string method descriptor. The comparison
@@ -181,6 +188,14 @@ int dexProtoCompareParameters(const DexProto* pProto1, const DexProto* pProto2);
 int dexProtoCompareToDescriptor(const DexProto* proto, const char* descriptor);
 
 /*
+ * Compare a prototype and a concatenation of type descriptors. The
+ * comparison is done as if the descriptors were converted to a
+ * prototype and compared with dexProtoCompareParameters().
+ */
+int dexProtoCompareToParameterDescriptors(const DexProto* proto,
+        const char* descriptors);
+
+/*
  * Single-thread prototype parameter iterator. This structure holds a
  * pointer to a prototype and its parts, along with a cursor.
  */
index 1f65a23..dd9dce4 100644 (file)
@@ -29,6 +29,9 @@
 
 #include <JNIHelp.h>        // TEMP_FAILURE_RETRY may or may not be in unistd
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
 
 /*
  * Zip file constants.
@@ -341,7 +344,7 @@ int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive)
 
     memset(pArchive, 0, sizeof(ZipArchive));
 
-    fd = open(fileName, O_RDONLY, 0);
+    fd = open(fileName, O_RDONLY | O_BINARY, 0);
     if (fd < 0) {
         err = errno ? errno : -1;
         LOGV("Unable to open '%s': %s\n", fileName, strerror(err));
index ededb4c..e5abc0f 100644 (file)
@@ -21,6 +21,7 @@
 #include "JNIHelp.h"
 #include "utils/Log.h"
 
+#include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 
@@ -337,3 +338,38 @@ int jniGetFDFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) {
 void jniSetFileDescriptorOfFD(JNIEnv* env, jobject fileDescriptor, int value) {
     (*env)->SetIntField(env, fileDescriptor, gCachedFields.descriptorField, value);
 }
+
+/*
+ * DO NOT USE THIS FUNCTION
+ *
+ * Get a pointer to the elements of a non-movable array.
+ *
+ * The semantics are similar to GetDirectBufferAddress.  Specifically, the VM
+ * guarantees that the array will not move, and the caller must ensure that
+ * it does not continue to use the pointer after the object is collected.
+ *
+ * We currently use an illegal sequence that trips up CheckJNI when
+ * the "forcecopy" mode is enabled.  We pass in a magic value to work
+ * around the problem.
+ *
+ * Returns NULL if the array is movable.
+ */
+jbyte* jniGetNonMovableArrayElements(JNIEnv* env, jarray arrayObj)
+{
+#define kNoCopyMagic 0xd5aab57f     /* also in CheckJni.c */
+
+    /*
+     * Normally the "isCopy" parameter is for a return value only, so the
+     * non-CheckJNI VM will ignore whatever we pass in.
+     */
+    uint32_t noCopy = kNoCopyMagic;
+    jbyte *addr = (*env)->GetByteArrayElements(env, arrayObj,
+            (jboolean*)&noCopy);
+
+    /*
+     * The non-CheckJNI implementation only cares about the array object,
+     * so we can replace the element pointer with the magic value.
+     */
+    (*env)->ReleaseByteArrayElements(env, arrayObj, (jbyte*) kNoCopyMagic, 0);
+    return addr;
+}
index 1c9f933..71ecf38 100644 (file)
@@ -106,7 +106,7 @@ void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable ex
  * For C++ code, we provide inlines that map to the C functions.  g++ always
  * inlines these, even on non-optimized builds.
  */
-#if defined(__cplusplus) && !defined(JNI_FORCE_C)
+#if defined(__cplusplus)
 inline int jniRegisterNativeMethods(JNIEnv* env, const char* className,
     const JNINativeMethod* gMethods, int numMethods)
 {
index 0ef2029..724786e 100644 (file)
@@ -2,3 +2,14 @@ string -> object
 object -> string
 object -> string (modified)
 caught ArrayStoreException (expected)
+copy: 0,0,0: [0, 1, 2, 3, 4, 5, 6, 7]
+copy: 0,0,8: [0, 1, 2, 3, 4, 5, 6, 7]
+copy: 0,2,4: [0, 1, 0, 1, 2, 3, 6, 7]
+copy: 2,0,4: [2, 3, 4, 5, 4, 5, 6, 7]
+copy: 1,3,4: [0, 1, 2, 1, 2, 3, 4, 7]
+copy: 3,1,4: [0, 3, 4, 5, 6, 5, 6, 7]
+copy: 3,1,5: [0, 3, 4, 5, 6, 7, 6, 7]
+copy: 1,3,5: [0, 1, 2, 1, 2, 3, 4, 5]
+copy: 0,3,5: [0, 1, 2, 0, 1, 2, 3, 4]
+copy: 3,0,5: [3, 4, 5, 6, 7, 5, 6, 7]
+copy: 0,5,1: [0, 1, 2, 3, 4, 0, 6, 7]
index 9cb8238..505d8b0 100644 (file)
  * limitations under the License.
  */
 
+import java.util.Arrays;
+
 /**
  * System.arraycopy cases
  */
 public class Main {
     public static void main(String args[]) {
+        testObjectCopy();
+        testOverlappingMoves();
+    }
+
+    public static void testObjectCopy() {
         String[] stringArray = new String[8];
         Object[] objectArray = new Object[8];
 
@@ -38,4 +45,102 @@ public class Main {
             System.out.println("caught ArrayStoreException (expected)");
         }
     }
+
+    static final int ARRAY_SIZE = 8;
+
+    static void initByteArray(byte[] array) {
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i] = (byte) i;
+        }
+    }
+    static void initShortArray(short[] array) {
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i] = (short) i;
+        }
+    }
+    static void initIntArray(int[] array) {
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i] = (int) i;
+        }
+    }
+    static void initLongArray(long[] array) {
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i] = (long) i;
+        }
+    }
+
+    /*
+     * Perform an array copy operation on primitive arrays with different
+     * element widths.
+     */
+    static void makeCopies(int srcPos, int dstPos, int length) {
+        byte[] byteArray = new byte[ARRAY_SIZE];
+        short[] shortArray = new short[ARRAY_SIZE];
+        int[] intArray = new int[ARRAY_SIZE];
+        long[] longArray = new long[ARRAY_SIZE];
+
+        initByteArray(byteArray);
+        initShortArray(shortArray);
+        initIntArray(intArray);
+        initLongArray(longArray);
+
+        System.arraycopy(byteArray, srcPos, byteArray, dstPos, length);
+        System.arraycopy(shortArray, srcPos, shortArray, dstPos, length);
+        System.arraycopy(intArray, srcPos, intArray, dstPos, length);
+        System.arraycopy(longArray, srcPos, longArray, dstPos, length);
+
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            if (intArray[i] != byteArray[i]) {
+                System.out.println("mismatch int vs byte at " + i + " : " +
+                    Arrays.toString(byteArray));
+                break;
+            } else if (intArray[i] != shortArray[i]) {
+                System.out.println("mismatch int vs short at " + i + " : " +
+                    Arrays.toString(shortArray));
+                break;
+            } else if (intArray[i] != longArray[i]) {
+                System.out.println("mismatch int vs long at " + i + " : " +
+                    Arrays.toString(longArray));
+                break;
+            }
+        }
+
+        System.out.println("copy: " + srcPos + "," + dstPos + "," + length +
+            ": " + Arrays.toString(intArray));
+    }
+
+    public static void testOverlappingMoves() {
+        /* do nothing */
+        makeCopies(0, 0, 0);
+
+        /* do more nothing */
+        makeCopies(0, 0, ARRAY_SIZE);
+
+        /* copy forward, even alignment */
+        makeCopies(0, 2, 4);
+
+        /* copy backward, even alignment */
+        makeCopies(2, 0, 4);
+
+        /* copy forward, odd alignment */
+        makeCopies(1, 3, 4);
+
+        /* copy backward, odd alignment */
+        makeCopies(3, 1, 4);
+
+        /* copy backward, odd length */
+        makeCopies(3, 1, 5);
+
+        /* copy forward, odd length */
+        makeCopies(1, 3, 5);
+
+        /* copy forward, mixed alignment */
+        makeCopies(0, 3, 5);
+
+        /* copy backward, mixed alignment */
+        makeCopies(3, 0, 5);
+
+        /* copy forward, mixed alignment, trivial length */
+        makeCopies(0, 5, 1);
+    }
 }
index 7465976..aa04655 100644 (file)
@@ -44,7 +44,7 @@ include $(LOCAL_PATH)/ReconfigureDvm.mk
 
 # Overwrite default settings
 ifneq ($(TARGET_ARCH),x86)
-ifeq ($(TARGET_SIMULATOR),false)
+ifneq ($(TARGET_SIMULATOR),true)
     LOCAL_PRELINK_MODULE := true
 endif
 endif
index f8815fb..fa65b50 100644 (file)
@@ -2121,6 +2121,14 @@ NEW_PRIMITIVE_ARRAY(jfloatArray, Float);
 NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
 
 
+/*
+ * Hack to allow forcecopy to work with jniGetNonMovableArrayElements.
+ * The code deliberately uses an invalid sequence of operations, so we
+ * need to pass it through unmodified.  Review that code before making
+ * any changes here.
+ */
+#define kNoCopyMagic    0xd5aab57f
+
 #define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                        \
     static _ctype* Check_Get##_jname##ArrayElements(JNIEnv* env,            \
         _ctype##Array array, jboolean* isCopy)                              \
@@ -2128,10 +2136,19 @@ NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
         CHECK_ENTER(env, kFlag_Default);                                    \
         CHECK_ARRAY(env, array);                                            \
         _ctype* result;                                                     \
+        u4 noCopy = 0;                                                      \
+        if (((JNIEnvExt*)env)->forceDataCopy && isCopy != NULL) {           \
+            /* capture this before the base call tramples on it */          \
+            noCopy = *(u4*) isCopy;                                         \
+        }                                                                   \
         result = BASE_ENV(env)->Get##_jname##ArrayElements(env,             \
             array, isCopy);                                                 \
         if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {           \
-            result = (_ctype*) createGuardedPACopy(env, array, isCopy);     \
+            if (noCopy == kNoCopyMagic) {                                   \
+                LOGV("FC: not copying %p %x\n", array, noCopy);             \
+            } else {                                                        \
+                result = (_ctype*) createGuardedPACopy(env, array, isCopy); \
+            }                                                               \
         }                                                                   \
         CHECK_EXIT(env);                                                    \
         return result;                                                      \
@@ -2146,7 +2163,13 @@ NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
         CHECK_NON_NULL(env, elems);                                         \
         CHECK_RELEASE_MODE(env, mode);                                      \
         if (((JNIEnvExt*)env)->forceDataCopy) {                             \
-            elems = (_ctype*) releaseGuardedPACopy(env, array, elems, mode);\
+            if ((uintptr_t)elems == kNoCopyMagic) {                         \
+                LOGV("FC: not freeing %p\n", array);                        \
+                elems = NULL;   /* base JNI call doesn't currently need */  \
+            } else {                                                        \
+                elems = (_ctype*) releaseGuardedPACopy(env, array, elems,   \
+                        mode);                                              \
+            }                                                               \
         }                                                                   \
         BASE_ENV(env)->Release##_jname##ArrayElements(env,                  \
             array, elems, mode);                                            \
index d3d67dd..8502b34 100644 (file)
@@ -25,7 +25,7 @@
  */
 #define DALVIK_MAJOR_VERSION    1
 #define DALVIK_MINOR_VERSION    5
-#define DALVIK_BUG_VERSION      0
+#define DALVIK_BUG_VERSION      1
 
 /*
  * VM build number.  This must change whenever something that affects the
index de7523f..1147eca 100644 (file)
@@ -221,6 +221,7 @@ int dvmJarFileOpen(const char* fileName, const char* odexOutputName,
         if (!dvmCheckOptHeaderAndDependencies(fd, false, 0, 0, true, true)) {
             LOGE("%s odex has stale dependencies\n", fileName);
             free(cachedName);
+            cachedName = NULL;
             close(fd);
             fd = -1;
             goto tryArchive;
index a416b13..88f84ac 100644 (file)
--- a/vm/Jni.c
+++ b/vm/Jni.c
@@ -3205,13 +3205,13 @@ NEW_PRIMITIVE_ARRAY(jdoubleArray, Double, 'D');
         _ctype##Array jarr, _ctype* elems, jint mode)                       \
     {                                                                       \
         UNUSED_PARAMETER(elems);                                            \
-        JNI_ENTER();                                                        \
         if (mode != JNI_COMMIT) {                                           \
+            JNI_ENTER();                                                    \
             ArrayObject* arrayObj =                                         \
                 (ArrayObject*) dvmDecodeIndirectRef(env, jarr);             \
             unpinPrimitiveArray(arrayObj);                                  \
+            JNI_EXIT();                                                     \
         }                                                                   \
-        JNI_EXIT();                                                         \
     }
 
 static void throwArrayRegionOutOfBounds(ArrayObject* arrayObj, jsize start,
@@ -3466,12 +3466,12 @@ static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray jarr,
 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray jarr,
     void* carray, jint mode)
 {
-    JNI_ENTER();
     if (mode != JNI_COMMIT) {
+        JNI_ENTER();
         ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
         unpinPrimitiveArray(arrayObj);
+        JNI_EXIT();
     }
-    JNI_EXIT();
 }
 
 /*
index af31a3d..4fe0d2c 100644 (file)
@@ -30,9 +30,8 @@ bool dvmMterpStdRun(MterpGlue* glue)
      */
     changeInterp = setjmp(jmpBuf) -1;
     if (changeInterp >= 0) {
-        Thread* threadSelf = dvmThreadSelf();
         LOGVV("mterp threadid=%d returning %d\n",
-            threadSelf->threadId, changeInterp);
+            dvmThreadSelf()->threadId, changeInterp);
         return changeInterp;
     }
 
@@ -64,6 +63,7 @@ bool dvmMterpStdRun(MterpGlue* glue)
 
         u2 inst = /*glue->*/pc[0];
         Handler handler = (Handler) gDvmMterpHandlers[inst & 0xff];
+        (void) gDvmMterpHandlerNames;   /* avoid gcc "defined but not used" */
         LOGVV("handler %p %s\n",
             handler, (const char*) gDvmMterpHandlerNames[inst & 0xff]);
         (*handler)(glue);
index 136e2f2..d4dd705 100644 (file)
 .LintMax:
 .long   0x7FFFFFFF
 
+
     .global dvmAsmInstructionStart
     .type   dvmAsmInstructionStart, %function
 dvmAsmInstructionStart = .L_OP_NOP
index 5d8e3d6..fb72f26 100644 (file)
@@ -3079,9 +3079,8 @@ bool dvmMterpStdRun(MterpGlue* glue)
      */
     changeInterp = setjmp(jmpBuf) -1;
     if (changeInterp >= 0) {
-        Thread* threadSelf = dvmThreadSelf();
         LOGVV("mterp threadid=%d returning %d\n",
-            threadSelf->threadId, changeInterp);
+            dvmThreadSelf()->threadId, changeInterp);
         return changeInterp;
     }
 
@@ -3113,12 +3112,14 @@ bool dvmMterpStdRun(MterpGlue* glue)
 
         u2 inst = /*glue->*/pc[0];
         Handler handler = (Handler) gDvmMterpHandlers[inst & 0xff];
+        (void) gDvmMterpHandlerNames;   /* avoid gcc "defined but not used" */
         LOGVV("handler %p %s\n",
             handler, (const char*) gDvmMterpHandlerNames[inst & 0xff]);
         (*handler)(glue);
     }
 }
 
+
 /*
  * C mterp exit point.  Call here to bail out of the interpreter.
  */
index 7c601d8..e15b432 100644 (file)
@@ -197,6 +197,7 @@ static void Dalvik_dalvik_system_DexFile_openDexFile(const u4* args,
         dvmThrowException("Ljava/io/IOException;",
             "Re-opening BOOTCLASSPATH DEX files is not allowed");
         free(sourceName);
+        free(outputName);
         RETURN_VOID();
     }
 
index 4e6efd8..55fb684 100644 (file)
@@ -594,8 +594,10 @@ static void Dalvik_dalvik_system_VMDebug_dumpHprofData(const u4* args,
     int fd = -1;
     if (fileDescriptor != NULL) {
         fd = getFileDescriptor(fileDescriptor);
-        if (fd < 0)
+        if (fd < 0) {
+            free(fileName);
             RETURN_VOID();
+        }
     }
 
     result = hprofDumpHeap(fileName, fd, false);
index bcc2313..c568005 100644 (file)
@@ -299,7 +299,7 @@ static void enableDebugFeatures(u4 debugFlags)
 #endif
     }
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     if ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0) {
         /* To let a non-privileged gdbserver attach to this
          * process, we must set its dumpable bit flag. However
index 3bb6885..1cd31df 100644 (file)
@@ -275,6 +275,25 @@ static void Dalvik_java_lang_Class_getDeclaredMethods(const u4* args,
 }
 
 /*
+ * static native Member getDeclaredConstructorOrMethod(
+ *     Class clazz, String name, Class[] args);
+ */
+static void Dalvik_java_lang_Class_getDeclaredConstructorOrMethod(
+    const u4* args, JValue* pResult)
+{
+    ClassObject* clazz = (ClassObject*) args[0];
+    StringObject* nameObj = (StringObject*) args[1];
+    ArrayObject* methodArgs = (ArrayObject*) args[2];
+
+    Object* methodObj;
+
+    methodObj = dvmGetDeclaredConstructorOrMethod(clazz, nameObj, methodArgs);
+    dvmReleaseTrackedAlloc(methodObj, NULL);
+
+    RETURN_PTR(methodObj);
+}
+
+/*
  * Class[] getInterfaces()
  */
 static void Dalvik_java_lang_Class_getInterfaces(const u4* args,
@@ -741,6 +760,8 @@ const DalvikNativeMethod dvm_java_lang_Class[] = {
         Dalvik_java_lang_Class_getDeclaredFields },
     { "getDeclaredMethods",     "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",
         Dalvik_java_lang_Class_getDeclaredMethods },
+    { "getDeclaredConstructorOrMethod", "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;",
+        Dalvik_java_lang_Class_getDeclaredConstructorOrMethod },
     { "getInterfaces",          "()[Ljava/lang/Class;",
         Dalvik_java_lang_Class_getInterfaces },
     { "getModifiers",           "(Ljava/lang/Class;Z)I",
index 4af0dfa..0ac1746 100644 (file)
  */
 
 /*
- * java.lang.Class
+ * java.lang.Class native methods
  */
 #include "Dalvik.h"
 #include "native/InternalNativePriv.h"
 
 /*
- * Call the appropriate copy function given the circumstances.
+ * The VM makes guarantees about the atomicity of accesses to primitive
+ * variables.  These guarantees also apply to elements of arrays.
+ * In particular, 8-bit, 16-bit, and 32-bit accesses must be atomic and
+ * must not cause "word tearing".  Accesses to 64-bit array elements must
+ * either be atomic or treated as two 32-bit operations.  References are
+ * always read and written atomically, regardless of the number of bits
+ * used to represent them.
+ *
+ * We can't rely on standard libc functions like memcpy() and memmove()
+ * in our implementation of System.arraycopy(), because they may copy
+ * byte-by-byte (either for the full run or for "unaligned" parts at the
+ * start or end).  We need to use functions that guarantee 16-bit or 32-bit
+ * atomicity as appropriate.
+ *
+ * System.arraycopy() is heavily used, so having an efficient implementation
+ * is important.  The bionic libc provides a platform-optimized memory move
+ * function that should be used when possible.  If it's not available,
+ * the trivial "reference implementation" versions below can be used until
+ * a proper version can be written.
+ *
+ * For these functions, The caller must guarantee that dest/src are aligned
+ * appropriately for the element type, and that n is a multiple of the
+ * element size.
  */
-static void copy(void *dest, const void *src, size_t n, bool sameArray,
-        size_t elemSize)
+#ifdef __BIONIC__
+/* always present in bionic libc */
+#define HAVE_MEMMOVE_WORDS
+#endif
+
+#ifdef HAVE_MEMMOVE_WORDS
+extern void _memmove_words(void* dest, const void* src, size_t n);
+#define move16 _memmove_words
+#define move32 _memmove_words
+#else
+static void move16(void* dest, const void* src, size_t n)
 {
-    if (sameArray) {
-        /* Might overlap. */
-        if (elemSize == sizeof(Object*)) {
-            /*
-             * In addition to handling overlap properly, bcopy()
-             * guarantees atomic treatment of words. This is needed so
-             * that concurrent threads never see half-formed pointers
-             * or ints. The former is required for proper gc behavior,
-             * and the latter is also required for proper high-level
-             * language support.
-             *
-             * Note: bcopy()'s argument order is different than memcpy().
-             */
-            bcopy(src, dest, n);
-        } else {
-            memmove(dest, src, n);
+    assert((((uintptr_t) dest | (uintptr_t) src | n) & 0x01) == 0);
+
+    uint16_t* d = (uint16_t*) dest;
+    const uint16_t* s = (uint16_t*) src;
+
+    n /= sizeof(uint16_t);
+
+    if (d < s) {
+        /* copy forward */
+        while (n--) {
+            *d++ = *s++;
         }
     } else {
-        memcpy(dest, src, n); /* Can't overlap; use faster function. */
+        /* copy backward */
+        d += n;
+        s += n;
+        while (n--) {
+            *--d = *--s;
+        }
     }
 }
 
+static void move32(void* dest, const void* src, size_t n)
+{
+    assert((((uintptr_t) dest | (uintptr_t) src | n) & 0x03) == 0);
+
+    uint32_t* d = (uint32_t*) dest;
+    const uint32_t* s = (uint32_t*) src;
+
+    n /= sizeof(uint32_t);
+
+    if (d < s) {
+        /* copy forward */
+        while (n--) {
+            *d++ = *s++;
+        }
+    } else {
+        /* copy backward */
+        d += n;
+        s += n;
+        while (n--) {
+            *--d = *--s;
+        }
+    }
+}
+#endif /*HAVE_MEMMOVE_WORDS*/
+
 /*
  * public static void arraycopy(Object src, int srcPos, Object dest,
  *      int destPos, int length)
@@ -64,7 +120,6 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
     int srcPos, dstPos, length;
     char srcType, dstType;
     bool srcPrim, dstPrim;
-    bool sameArray;
 
     srcArray = (ArrayObject*) args[0];
     srcPos = args[1];
@@ -72,8 +127,6 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
     dstPos = args[3];
     length = args[4];
 
-    sameArray = (srcArray == dstArray);
-
     /* check for null or bad pointer */
     if (!dvmValidateObject((Object*)srcArray) ||
         !dvmValidateObject((Object*)dstArray))
@@ -81,6 +134,7 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
         assert(dvmCheckException(dvmThreadSelf()));
         RETURN_VOID();
     }
+
     /* make sure it's an array */
     if (!dvmIsArray(srcArray) || !dvmIsArray(dstArray)) {
         dvmThrowExceptionFmt("Ljava/lang/ArrayStoreException;",
@@ -90,7 +144,7 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
         RETURN_VOID();
     }
 
-    // avoid int overflow
+    /* avoid int overflow */
     if (srcPos < 0 || dstPos < 0 || length < 0 ||
         srcPos > (int) srcArray->length - length ||
         dstPos > (int) dstArray->length - length)
@@ -113,8 +167,6 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
     srcPrim = (srcType != '[' && srcType != 'L');
     dstPrim = (dstType != '[' && dstType != 'L');
     if (srcPrim || dstPrim) {
-        int width;
-
         if (srcPrim != dstPrim || srcType != dstType) {
             dvmThrowExceptionFmt("Ljava/lang/ArrayStoreException;",
                 "source and destination arrays are incompatible: %s and %s",
@@ -122,45 +174,53 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
             RETURN_VOID();
         }
 
-        switch (srcClass->descriptor[1]) {
+        if (false) LOGD("arraycopy prim[%c] dst=%p %d src=%p %d len=%d\n",
+            srcType, dstArray->contents, dstPos,
+            srcArray->contents, srcPos, length);
+
+        switch (srcType) {
         case 'B':
         case 'Z':
-            width = 1;
+            /* 1 byte per element */
+            memmove((u1*) dstArray->contents + dstPos,
+                (const u1*) srcArray->contents + srcPos,
+                length);
             break;
         case 'C':
         case 'S':
-            width = 2;
+            /* 2 bytes per element */
+            move16((u1*) dstArray->contents + dstPos * 2,
+                (const u1*) srcArray->contents + srcPos * 2,
+                length * 2);
             break;
         case 'F':
         case 'I':
-            width = 4;
+            /* 4 bytes per element */
+            move32((u1*) dstArray->contents + dstPos * 4,
+                (const u1*) srcArray->contents + srcPos * 4,
+                length * 4);
             break;
         case 'D':
         case 'J':
-            width = 8;
+            /*
+             * 8 bytes per element.  We don't need to guarantee atomicity
+             * of the entire 64-bit word, so we can use the 32-bit copier.
+             */
+            move32((u1*) dstArray->contents + dstPos * 8,
+                (const u1*) srcArray->contents + srcPos * 8,
+                length * 8);
             break;
-        default:        /* 'V' or something weird */
+        default:        /* illegal array type */
             LOGE("Weird array type '%s'\n", srcClass->descriptor);
-            assert(false);
-            width = 0;
-            break;
+            dvmAbort();
         }
-
-        if (false) LOGVV("arraycopy prim dst=%p %d src=%p %d len=%d\n",
-                dstArray->contents, dstPos * width,
-                srcArray->contents, srcPos * width,
-                length * width);
-        copy((u1*)dstArray->contents + dstPos * width,
-                (const u1*)srcArray->contents + srcPos * width,
-                length * width,
-                sameArray, width);
     } else {
         /*
          * Neither class is primitive.  See if elements in "src" are instances
          * of elements in "dst" (e.g. copy String to String or String to
          * Object).
          */
-        int width = sizeof(Object*);
+        const int width = sizeof(Object*);
 
         if (srcClass->arrayDim == dstClass->arrayDim &&
             dvmInstanceof(srcClass, dstClass))
@@ -168,27 +228,26 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
             /*
              * "dst" can hold "src"; copy the whole thing.
              */
-            if (false) LOGVV("arraycopy ref dst=%p %d src=%p %d len=%d\n",
+            if (false) LOGD("arraycopy ref dst=%p %d src=%p %d len=%d\n",
                 dstArray->contents, dstPos * width,
                 srcArray->contents, srcPos * width,
                 length * width);
-            copy((u1*)dstArray->contents + dstPos * width,
-                    (const u1*)srcArray->contents + srcPos * width,
-                    length * width,
-                    sameArray, width);
+            move32((u1*)dstArray->contents + dstPos * width,
+                (const u1*)srcArray->contents + srcPos * width,
+                length * width);
             dvmWriteBarrierArray(dstArray, dstPos, dstPos+length);
         } else {
             /*
-             * The arrays are not fundamentally compatible.  However, we may
-             * still be able to do this if the destination object is compatible
-             * (e.g. copy Object to String, but the Object being copied is
-             * actually a String).  We need to copy elements one by one until
-             * something goes wrong.
+             * The arrays are not fundamentally compatible.  However, we
+             * may still be able to do this if the destination object is
+             * compatible (e.g. copy Object[] to String[], but the Object
+             * being copied is actually a String).  We need to copy elements
+             * one by one until something goes wrong.
              *
-             * Because of overlapping moves, what we really want to do is
-             * compare the types and count up how many we can move, then call
-             * memmove() to shift the actual data.  If we just start from the
-             * front we could do a smear rather than a move.
+             * Because of overlapping moves, what we really want to do
+             * is compare the types and count up how many we can move,
+             * then call move32() to shift the actual data.  If we just
+             * start from the front we could do a smear rather than a move.
              */
             Object** srcObj;
             Object** dstObj;
@@ -216,14 +275,13 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult)
                 }
             }
 
-            if (false) LOGVV("arraycopy iref dst=%p %d src=%p %d count=%d of %d\n",
+            if (false) LOGD("arraycopy iref dst=%p %d src=%p %d count=%d of %d\n",
                 dstArray->contents, dstPos * width,
                 srcArray->contents, srcPos * width,
                 copyCount, length);
-            copy((u1*)dstArray->contents + dstPos * width,
-                    (const u1*)srcArray->contents + srcPos * width,
-                    copyCount * width,
-                    sameArray, width);
+            move32((u1*)dstArray->contents + dstPos * width,
+                (const u1*)srcArray->contents + srcPos * width,
+                copyCount * width);
             dvmWriteBarrierArray(dstArray, 0, copyCount);
             if (copyCount != length) {
                 dvmThrowExceptionFmt("Ljava/lang/ArrayStoreException;",
index 4fc0e5c..fd37da0 100644 (file)
@@ -710,6 +710,9 @@ INLINE bool dvmIsNativeMethod(const Method* method) {
 INLINE bool dvmIsAbstractMethod(const Method* method) {
     return (method->accessFlags & ACC_ABSTRACT) != 0;
 }
+INLINE bool dvmIsSyntheticMethod(const Method* method) {
+    return (method->accessFlags & ACC_SYNTHETIC) != 0;
+}
 INLINE bool dvmIsMirandaMethod(const Method* method) {
     return (method->accessFlags & ACC_MIRANDA) != 0;
 }
index 2a7c740..48eb477 100644 (file)
@@ -817,6 +817,102 @@ fail:
 }
 
 /*
+ * Fills targetDescriptorCache with the descriptors of the classes in args.
+ * This is the concatenation of the descriptors with no other adornment,
+ * consistent with dexProtoGetParameterDescriptors.
+ */
+static void createTargetDescriptor(ArrayObject* args,
+    DexStringCache* targetDescriptorCache)
+{
+    size_t i;
+    ClassObject** argsArray = NULL;
+    size_t length;
+    char* at;
+    const char* descriptor;
+
+    argsArray = (ClassObject**) args->contents;
+
+    length = 1; /* +1 for the terminating '\0' */
+    for (i = 0; i < args->length; ++i) {
+        length += strlen(argsArray[i]->descriptor);
+    }
+
+    dexStringCacheAlloc(targetDescriptorCache, length);
+
+    at = (char*) targetDescriptorCache->value;
+    for (i = 0; i < args->length; ++i) {
+        descriptor = argsArray[i]->descriptor;
+        strcpy(at, descriptor);
+        at += strlen(descriptor);
+    }
+}
+
+static Object* findConstructorOrMethodInArray(int methodsCount, Method* methods,
+    const char* name, const char* parameterDescriptors)
+{
+    Method* method = NULL;
+    Method* result = NULL;
+    int i;
+
+    for (i = 0; i < methodsCount; ++i) {
+        method = &methods[i];
+        if (strcmp(name, method->name) != 0
+            || dvmIsMirandaMethod(method)
+            || dexProtoCompareToParameterDescriptors(&method->prototype,
+                    parameterDescriptors) != 0) {
+            continue;
+        }
+
+        result = method;
+
+        /*
+         * Covariant return types permit the class to define multiple
+         * methods with the same name and parameter types. Prefer to return
+         * a non-synthetic method in such situations. We may still return
+         * a synthetic method to handle situations like escalated visibility.
+         */
+        if (!dvmIsSyntheticMethod(method)) {
+            break;
+        }
+    }
+
+    if (result != NULL) {
+        return dvmCreateReflectObjForMethod(result->clazz, result);
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the named method.
+ */
+Object* dvmGetDeclaredConstructorOrMethod(ClassObject* clazz,
+    StringObject* nameObj, ArrayObject* args)
+{
+    Object* result = NULL;
+    DexStringCache targetDescriptorCache;
+    char* name;
+    const char* targetDescriptor;
+
+    dexStringCacheInit(&targetDescriptorCache);
+
+    name = dvmCreateCstrFromString(nameObj);
+    createTargetDescriptor(args, &targetDescriptorCache);
+    targetDescriptor = targetDescriptorCache.value;
+
+    result = findConstructorOrMethodInArray(clazz->directMethodCount,
+        clazz->directMethods, name, targetDescriptor);
+    if (result == NULL) {
+        result = findConstructorOrMethodInArray(clazz->virtualMethodCount,
+            clazz->virtualMethods, name, targetDescriptor);
+    }
+
+    free(name);
+    dexStringCacheRelease(&targetDescriptorCache);
+    return result;
+}
+
+/*
  * Get all interfaces a class implements. If this is unable to allocate
  * the result array, this raises an OutOfMemoryError and returns NULL.
  */
index c9a9a22..42b18c0 100644 (file)
@@ -51,6 +51,12 @@ ArrayObject* dvmGetDeclaredConstructors(ClassObject* clazz, bool publicOnly);
 ArrayObject* dvmGetDeclaredMethods(ClassObject* clazz, bool publicOnly);
 
 /*
+ * Get the named method.
+ */
+Object* dvmGetDeclaredConstructorOrMethod(ClassObject* clazz,
+    StringObject* nameObj, ArrayObject* args);
+
+/*
  * Get all interfaces a class implements. If this is unable to allocate
  * the result array, this raises an OutOfMemoryError and returns NULL.
  */