summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/x86/NcgHelper.cpp
diff options
context:
space:
mode:
authorDong-Yuan Chen <dong-yuan.chen@intel.com>2012-07-03 13:13:07 -0700
committerElliott Hughes <enh@google.com>2012-07-20 12:27:18 -0700
commit0c2dc522d0e120f346cf0a40c8cf0c93346131c2 (patch)
treef7ca4c8e3ca1150b7e8c5f4b68c60972641dc77f /vm/compiler/codegen/x86/NcgHelper.cpp
parentabede656a1f2330e3d31281fb208be7c04e8eb56 (diff)
downloadandroid_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.tar.gz
android_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.tar.bz2
android_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.zip
[X86] X86 trace JIT compiler support
This patch provides a fully functional x86 trace JIT compiler for Dalvik VM. It is built on top of the existing x86 fast interpreter with bug fixes and needed extension to support trace JIT interface. The x86 trace JIT code generator was developed independent of the existing template-based code generator and thus does not share exactly the same infrastructure. Included in this patch are: * Deprecated and removed the x86-atom fast interpreter that is no longer functional since ICS. * Augmented x86 fast interpreter to provide interfaces for x86 trace JIT compiler. * Added x86 trace JIT code generator with full JDWP debugging support. * Method JIT and self-verification mode are not supported. The x86 code generator uses the x86 instruction encoder/decoder library from the Apache Harmony project. Additional wrapper extension and bug fixes were added to support the x86 trace JIT code generator. The x86 instruction encoder/decoder is embedded inside the x86 code generator under the libenc subdirectory. Change-Id: I241113681963a16c13a3562390813cbaaa6eedf0 Signed-off-by: Dong-Yuan Chen <dong-yuan.chen@intel.com> Signed-off-by: Yixin Shou <yixin.shou@intel.com> Signed-off-by: Johnnie Birch <johnnie.l.birch.jr@intel.com> Signed-off-by: Udayan <udayan.banerji@intel.com> Signed-off-by: Sushma Kyasaralli Thimmappa <sushma.kyasaralli.thimmappa@intel.com> Signed-off-by: Bijoy Jose <bijoy.a.jose@intel.com> Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com> Signed-off-by: Tim Hartley <timothy.d.hartley@intel.com>
Diffstat (limited to 'vm/compiler/codegen/x86/NcgHelper.cpp')
-rw-r--r--vm/compiler/codegen/x86/NcgHelper.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/vm/compiler/codegen/x86/NcgHelper.cpp b/vm/compiler/codegen/x86/NcgHelper.cpp
new file mode 100644
index 000000000..f9192dbdb
--- /dev/null
+++ b/vm/compiler/codegen/x86/NcgHelper.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+
+#include "Dalvik.h"
+#include "NcgHelper.h"
+#include "interp/InterpDefs.h"
+
+
+/*
+ * Find the matching case. Returns the offset to the handler instructions.
+ *
+ * Returns 3 if we don't find a match (it's the size of the packed-switch
+ * instruction).
+ */
+s4 dvmNcgHandlePackedSwitch(const s4* entries, s4 firstKey, u2 size, s4 testVal)
+{
+ //skip add_reg_reg (ADD_REG_REG_SIZE) and jump_reg (JUMP_REG_SIZE)
+ const int kInstrLen = 4; //default to next bytecode
+ if (testVal < firstKey || testVal >= firstKey + size) {
+ LOGVV("Value %d not found in switch (%d-%d)",
+ testVal, firstKey, firstKey+size-1);
+ return kInstrLen;
+ }
+
+ assert(testVal - firstKey >= 0 && testVal - firstKey < size);
+ LOGVV("Value %d found in slot %d (goto 0x%02x)",
+ testVal, testVal - firstKey,
+ s4FromSwitchData(&entries[testVal - firstKey]));
+ return s4FromSwitchData(&entries[testVal - firstKey]);
+
+}
+/* return the number of bytes to increase the bytecode pointer by */
+s4 dvmJitHandlePackedSwitch(const s4* entries, s4 firstKey, u2 size, s4 testVal)
+{
+ if (testVal < firstKey || testVal >= firstKey + size) {
+ LOGVV("Value %d not found in switch (%d-%d)",
+ testVal, firstKey, firstKey+size-1);
+ return 2*3;//bytecode packed_switch is 6(2*3) bytes long
+ }
+
+ LOGVV("Value %d found in slot %d (goto 0x%02x)",
+ testVal, testVal - firstKey,
+ s4FromSwitchData(&entries[testVal - firstKey]));
+ return 2*s4FromSwitchData(&entries[testVal - firstKey]); //convert from u2 to byte
+
+}
+/*
+ * Find the matching case. Returns the offset to the handler instructions.
+ *
+ * Returns 3 if we don't find a match (it's the size of the sparse-switch
+ * instruction).
+ */
+s4 dvmNcgHandleSparseSwitch(const s4* keys, u2 size, s4 testVal)
+{
+ const int kInstrLen = 4; //CHECK
+ const s4* entries = keys + size;
+ int i;
+ for (i = 0; i < size; i++) {
+ s4 k = s4FromSwitchData(&keys[i]);
+ if (k == testVal) {
+ LOGVV("Value %d found in entry %d (goto 0x%02x)",
+ testVal, i, s4FromSwitchData(&entries[i]));
+ return s4FromSwitchData(&entries[i]);
+ } else if (k > testVal) {
+ break;
+ }
+ }
+
+ LOGVV("Value %d not found in switch", testVal);
+ return kInstrLen;
+}
+/* return the number of bytes to increase the bytecode pointer by */
+s4 dvmJitHandleSparseSwitch(const s4* keys, u2 size, s4 testVal)
+{
+ const s4* entries = keys + size;
+ int i;
+ for (i = 0; i < size; i++) {
+ s4 k = s4FromSwitchData(&keys[i]);
+ if (k == testVal) {
+ LOGVV("Value %d found in entry %d (goto 0x%02x)",
+ testVal, i, s4FromSwitchData(&entries[i]));
+ return 2*s4FromSwitchData(&entries[i]); //convert from u2 to byte
+ } else if (k > testVal) {
+ break;
+ }
+ }
+
+ LOGVV("Value %d not found in switch", testVal);
+ return 2*3; //bytecode sparse_switch is 6(2*3) bytes long
+}
+/*
+ * Look up an interface on a class using the cache.
+ */
+/*INLINE*/ Method* dvmFindInterfaceMethodInCache2(ClassObject* thisClass,
+ u4 methodIdx, const Method* method, DvmDex* methodClassDex)
+{
+#define ATOMIC_CACHE_CALC \
+ dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex)
+
+ return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache,
+ DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx);
+
+#undef ATOMIC_CACHE_CALC
+}