PageRenderTime 52ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 727 lines | 264 code | 82 blank | 381 comment | 45 complexity | ee7501e97e6a9d903c9e9cc18a0b5289 MD5 | raw file
  1. /***
  2. * ASM: a very small and fast Java bytecode manipulation framework
  3. * Copyright (c) 2000-2007 INRIA, France Telecom
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  28. * THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. package com.alibaba.fastjson.asm;
  31. /**
  32. * A {@link ClassVisitor} that generates classes in bytecode form. More precisely this visitor generates a byte array
  33. * conforming to the Java class file format. It can be used alone, to generate a Java class "from scratch", or with one
  34. * or more and adapter class visitor to generate a modified class from one or more existing Java classes.
  35. *
  36. * @author Eric Bruneton
  37. */
  38. public class ClassWriter {
  39. /**
  40. * Flag to automatically compute the maximum stack size and the maximum number of local variables of methods. If
  41. * this flag is set, then the arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
  42. * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod} method will be ignored, and computed
  43. * automatically from the signature and the bytecode of each method.
  44. *
  45. * @see #ClassWriter(int)
  46. */
  47. public static final int COMPUTE_MAXS = 1;
  48. /**
  49. * Flag to automatically compute the stack map frames of methods from scratch. If this flag is set, then the calls
  50. * to the {@link MethodVisitor#visitFrame} method are ignored, and the stack map frames are recomputed from the
  51. * methods bytecode. The arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
  52. * recomputed from the bytecode. In other words, computeFrames implies computeMaxs.
  53. *
  54. * @see #ClassWriter(int)
  55. */
  56. public static final int COMPUTE_FRAMES = 2;
  57. /**
  58. * Pseudo access flag to distinguish between the synthetic attribute and the synthetic access flag.
  59. */
  60. static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
  61. /**
  62. * The type of instructions without any argument.
  63. */
  64. static final int NOARG_INSN = 0;
  65. /**
  66. * The type of instructions with an signed byte argument.
  67. */
  68. static final int SBYTE_INSN = 1;
  69. /**
  70. * The type of instructions with an signed short argument.
  71. */
  72. static final int SHORT_INSN = 2;
  73. /**
  74. * The type of instructions with a local variable index argument.
  75. */
  76. static final int VAR_INSN = 3;
  77. /**
  78. * The type of instructions with an implicit local variable index argument.
  79. */
  80. static final int IMPLVAR_INSN = 4;
  81. /**
  82. * The type of instructions with a type descriptor argument.
  83. */
  84. static final int TYPE_INSN = 5;
  85. /**
  86. * The type of field and method invocations instructions.
  87. */
  88. static final int FIELDORMETH_INSN = 6;
  89. /**
  90. * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
  91. */
  92. static final int ITFDYNMETH_INSN = 7;
  93. /**
  94. * The type of instructions with a 2 bytes bytecode offset label.
  95. */
  96. static final int LABEL_INSN = 8;
  97. /**
  98. * The type of instructions with a 4 bytes bytecode offset label.
  99. */
  100. static final int LABELW_INSN = 9;
  101. /**
  102. * The type of the LDC instruction.
  103. */
  104. static final int LDC_INSN = 10;
  105. /**
  106. * The type of the LDC_W and LDC2_W instructions.
  107. */
  108. static final int LDCW_INSN = 11;
  109. /**
  110. * The type of the IINC instruction.
  111. */
  112. static final int IINC_INSN = 12;
  113. /**
  114. * The type of the TABLESWITCH instruction.
  115. */
  116. static final int TABL_INSN = 13;
  117. /**
  118. * The type of the LOOKUPSWITCH instruction.
  119. */
  120. static final int LOOK_INSN = 14;
  121. /**
  122. * The type of the MULTIANEWARRAY instruction.
  123. */
  124. static final int MANA_INSN = 15;
  125. /**
  126. * The type of the WIDE instruction.
  127. */
  128. static final int WIDE_INSN = 16;
  129. /**
  130. * The instruction types of all JVM opcodes.
  131. */
  132. static final byte[] TYPE;
  133. /**
  134. * The type of CONSTANT_Class constant pool items.
  135. */
  136. static final int CLASS = 7;
  137. /**
  138. * The type of CONSTANT_Fieldref constant pool items.
  139. */
  140. static final int FIELD = 9;
  141. /**
  142. * The type of CONSTANT_Methodref constant pool items.
  143. */
  144. static final int METH = 10;
  145. /**
  146. * The type of CONSTANT_InterfaceMethodref constant pool items.
  147. */
  148. static final int IMETH = 11;
  149. /**
  150. * The type of CONSTANT_String constant pool items.
  151. */
  152. static final int STR = 8;
  153. /**
  154. * The type of CONSTANT_Integer constant pool items.
  155. */
  156. static final int INT = 3;
  157. /**
  158. * The type of CONSTANT_Float constant pool items.
  159. */
  160. static final int FLOAT = 4;
  161. /**
  162. * The type of CONSTANT_Long constant pool items.
  163. */
  164. static final int LONG = 5;
  165. /**
  166. * The type of CONSTANT_Double constant pool items.
  167. */
  168. static final int DOUBLE = 6;
  169. /**
  170. * The type of CONSTANT_NameAndType constant pool items.
  171. */
  172. static final int NAME_TYPE = 12;
  173. /**
  174. * The type of CONSTANT_Utf8 constant pool items.
  175. */
  176. static final int UTF8 = 1;
  177. /**
  178. * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in order
  179. * to avoid clashes with normal constant pool items in the ClassWriter constant pool's hash table.
  180. */
  181. static final int TYPE_NORMAL = 13;
  182. /**
  183. * Uninitialized type Item stored in the ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in
  184. * order to avoid clashes with normal constant pool items in the ClassWriter constant pool's hash table.
  185. */
  186. static final int TYPE_UNINIT = 14;
  187. /**
  188. * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in order
  189. * to avoid clashes with normal constant pool items in the ClassWriter constant pool's hash table.
  190. */
  191. static final int TYPE_MERGED = 15;
  192. /**
  193. * Minor and major version numbers of the class to be generated.
  194. */
  195. int version;
  196. /**
  197. * Index of the next item to be added in the constant pool.
  198. */
  199. int index;
  200. /**
  201. * The constant pool of this class.
  202. */
  203. final ByteVector pool;
  204. /**
  205. * The constant pool's hash table data.
  206. */
  207. Item[] items;
  208. /**
  209. * The threshold of the constant pool's hash table.
  210. */
  211. int threshold;
  212. /**
  213. * A reusable key used to look for items in the {@link #items} hash table.
  214. */
  215. final Item key;
  216. /**
  217. * A reusable key used to look for items in the {@link #items} hash table.
  218. */
  219. final Item key2;
  220. /**
  221. * A reusable key used to look for items in the {@link #items} hash table.
  222. */
  223. final Item key3;
  224. /**
  225. * A type table used to temporarily store internal names that will not necessarily be stored in the constant pool.
  226. * This type table is used by the control flow and data flow analysis algorithm used to compute stack map frames
  227. * from scratch. This array associates to each index <tt>i</tt> the Item whose index is <tt>i</tt>. All Item objects
  228. * stored in this array are also stored in the {@link #items} hash table. These two arrays allow to retrieve an Item
  229. * from its index or, conversely, to get the index of an Item from its value. Each Item stores an internal name in
  230. * its {@link Item#strVal1} field.
  231. */
  232. Item[] typeTable;
  233. /**
  234. * The access flags of this class.
  235. */
  236. private int access;
  237. /**
  238. * The constant pool item that contains the internal name of this class.
  239. */
  240. private int name;
  241. /**
  242. * The internal name of this class.
  243. */
  244. String thisName;
  245. /**
  246. * The constant pool item that contains the internal name of the super class of this class.
  247. */
  248. private int superName;
  249. /**
  250. * Number of interfaces implemented or extended by this class or interface.
  251. */
  252. private int interfaceCount;
  253. /**
  254. * The interfaces implemented or extended by this class or interface. More precisely, this array contains the
  255. * indexes of the constant pool items that contain the internal names of these interfaces.
  256. */
  257. private int[] interfaces;
  258. /**
  259. * The fields of this class. These fields are stored in a linked list of {@link FieldWriter} objects, linked to each
  260. * other by their {@link FieldWriter#next} field. This field stores the first element of this list.
  261. */
  262. FieldWriter firstField;
  263. /**
  264. * The fields of this class. These fields are stored in a linked list of {@link FieldWriter} objects, linked to each
  265. * other by their {@link FieldWriter#next} field. This field stores the last element of this list.
  266. */
  267. FieldWriter lastField;
  268. /**
  269. * The methods of this class. These methods are stored in a linked list of {@link MethodWriter} objects, linked to
  270. * each other by their {@link MethodWriter#next} field. This field stores the first element of this list.
  271. */
  272. MethodWriter firstMethod;
  273. /**
  274. * The methods of this class. These methods are stored in a linked list of {@link MethodWriter} objects, linked to
  275. * each other by their {@link MethodWriter#next} field. This field stores the last element of this list.
  276. */
  277. MethodWriter lastMethod;
  278. // ------------------------------------------------------------------------
  279. // Static initializer
  280. // ------------------------------------------------------------------------
  281. /**
  282. * Computes the instruction types of JVM opcodes.
  283. */
  284. static {
  285. int i;
  286. byte[] b = new byte[220];
  287. String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA" + "AAAAGGGGGGGHHFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
  288. for (i = 0; i < b.length; ++i) {
  289. b[i] = (byte) (s.charAt(i) - 'A');
  290. }
  291. TYPE = b;
  292. // code to generate the above string
  293. //
  294. // // SBYTE_INSN instructions
  295. // b[Constants.NEWARRAY] = SBYTE_INSN;
  296. // b[Constants.BIPUSH] = SBYTE_INSN;
  297. //
  298. // // SHORT_INSN instructions
  299. // b[Constants.SIPUSH] = SHORT_INSN;
  300. //
  301. // // (IMPL)VAR_INSN instructions
  302. // b[Constants.RET] = VAR_INSN;
  303. // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
  304. // b[i] = VAR_INSN;
  305. // }
  306. // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
  307. // b[i] = VAR_INSN;
  308. // }
  309. // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
  310. // b[i] = IMPLVAR_INSN;
  311. // }
  312. // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
  313. // b[i] = IMPLVAR_INSN;
  314. // }
  315. //
  316. // // TYPE_INSN instructions
  317. // b[Constants.NEW] = TYPE_INSN;
  318. // b[Constants.ANEWARRAY] = TYPE_INSN;
  319. // b[Constants.CHECKCAST] = TYPE_INSN;
  320. // b[Constants.INSTANCEOF] = TYPE_INSN;
  321. //
  322. // // (Set)FIELDORMETH_INSN instructions
  323. // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
  324. // b[i] = FIELDORMETH_INSN;
  325. // }
  326. // b[Constants.INVOKEINTERFACE] = ITFDYNMETH_INSN;
  327. // b[Constants.INVOKEDYNAMIC] = ITFDYNMETH_INSN;
  328. //
  329. // // LABEL(W)_INSN instructions
  330. // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
  331. // b[i] = LABEL_INSN;
  332. // }
  333. // b[Constants.IFNULL] = LABEL_INSN;
  334. // b[Constants.IFNONNULL] = LABEL_INSN;
  335. // b[200] = LABELW_INSN; // GOTO_W
  336. // b[201] = LABELW_INSN; // JSR_W
  337. // // temporary opcodes used internally by ASM - see Label and
  338. // MethodWriter
  339. // for (i = 202; i < 220; ++i) {
  340. // b[i] = LABEL_INSN;
  341. // }
  342. //
  343. // // LDC(_W) instructions
  344. // b[Constants.LDC] = LDC_INSN;
  345. // b[19] = LDCW_INSN; // LDC_W
  346. // b[20] = LDCW_INSN; // LDC2_W
  347. //
  348. // // special instructions
  349. // b[Constants.IINC] = IINC_INSN;
  350. // b[Constants.TABLESWITCH] = TABL_INSN;
  351. // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
  352. // b[Constants.MULTIANEWARRAY] = MANA_INSN;
  353. // b[196] = WIDE_INSN; // WIDE
  354. //
  355. // for (i = 0; i < b.length; ++i) {
  356. // System.err.print((char)('A' + b[i]));
  357. // }
  358. // System.err.println();
  359. }
  360. // ------------------------------------------------------------------------
  361. // Constructor
  362. // ------------------------------------------------------------------------
  363. public ClassWriter(){
  364. this(0);
  365. }
  366. /**
  367. * Constructs a new {@link ClassWriter} object.
  368. *
  369. * @param flags option flags that can be used to modify the default behavior of this class. See
  370. * {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
  371. */
  372. private ClassWriter(final int flags){
  373. index = 1;
  374. pool = new ByteVector();
  375. items = new Item[256];
  376. threshold = (int) (0.75d * items.length);
  377. key = new Item();
  378. key2 = new Item();
  379. key3 = new Item();
  380. }
  381. // ------------------------------------------------------------------------
  382. // Implementation of the ClassVisitor interface
  383. // ------------------------------------------------------------------------
  384. public void visit(final int version, final int access, final String name, final String superName, final String[] interfaces) {
  385. this.version = version;
  386. this.access = access;
  387. this.name = newClass(name);
  388. thisName = name;
  389. this.superName = superName == null ? 0 : newClass(superName);
  390. if (interfaces != null && interfaces.length > 0) {
  391. interfaceCount = interfaces.length;
  392. this.interfaces = new int[interfaceCount];
  393. for (int i = 0; i < interfaceCount; ++i) {
  394. this.interfaces[i] = newClass(interfaces[i]);
  395. }
  396. }
  397. }
  398. public FieldVisitor visitField(final int access, final String name, final String desc) {
  399. return new FieldWriter(this, access, name, desc);
  400. }
  401. public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
  402. return new MethodWriter(this, access, name, desc, signature, exceptions);
  403. }
  404. public void visitEnd() {
  405. }
  406. // ------------------------------------------------------------------------
  407. // Other public methods
  408. // ------------------------------------------------------------------------
  409. /**
  410. * Returns the bytecode of the class that was build with this class writer.
  411. *
  412. * @return the bytecode of the class that was build with this class writer.
  413. */
  414. public byte[] toByteArray() {
  415. // computes the real size of the bytecode of this class
  416. int size = 24 + 2 * interfaceCount;
  417. int nbFields = 0;
  418. FieldWriter fb = firstField;
  419. while (fb != null) {
  420. ++nbFields;
  421. size += fb.getSize();
  422. fb = fb.next;
  423. }
  424. int nbMethods = 0;
  425. MethodWriter mb = firstMethod;
  426. while (mb != null) {
  427. ++nbMethods;
  428. size += mb.getSize();
  429. mb = mb.next;
  430. }
  431. int attributeCount = 0;
  432. size += pool.length;
  433. // allocates a byte vector of this size, in order to avoid unnecessary
  434. // arraycopy operations in the ByteVector.enlarge() method
  435. ByteVector out = new ByteVector(size);
  436. out.putInt(0xCAFEBABE).putInt(version);
  437. out.putShort(index).putByteArray(pool.data, 0, pool.length);
  438. int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
  439. out.putShort(access & ~mask).putShort(name).putShort(superName);
  440. out.putShort(interfaceCount);
  441. for (int i = 0; i < interfaceCount; ++i) {
  442. out.putShort(interfaces[i]);
  443. }
  444. out.putShort(nbFields);
  445. fb = firstField;
  446. while (fb != null) {
  447. fb.put(out);
  448. fb = fb.next;
  449. }
  450. out.putShort(nbMethods);
  451. mb = firstMethod;
  452. while (mb != null) {
  453. mb.put(out);
  454. mb = mb.next;
  455. }
  456. out.putShort(attributeCount);
  457. return out.data;
  458. }
  459. // ------------------------------------------------------------------------
  460. // Utility methods: constant pool management
  461. // ------------------------------------------------------------------------
  462. /**
  463. * Adds a number or string constant to the constant pool of the class being build. Does nothing if the constant pool
  464. * already contains a similar item.
  465. *
  466. * @param cst the value of the constant to be added to the constant pool. This parameter must be an {@link Integer},
  467. * a {@link Float}, a {@link Long}, a {@link Double}, a {@link String} or a {@link Type}.
  468. * @return a new or already existing constant item with the given value.
  469. */
  470. Item newConstItem(final Object cst) {
  471. if (cst instanceof Integer) {
  472. int val = ((Integer) cst).intValue();
  473. return newInteger(val);
  474. } else if (cst instanceof String) {
  475. return newString((String) cst);
  476. } else if (cst instanceof Type) {
  477. Type t = (Type) cst;
  478. return newClassItem(t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor());
  479. } else {
  480. throw new IllegalArgumentException("value " + cst);
  481. }
  482. }
  483. Item newInteger(final int value) {
  484. key.set(value);
  485. Item result = get(key);
  486. if (result == null) {
  487. pool.putByte(INT).putInt(value);
  488. result = new Item(index++, key);
  489. put(result);
  490. }
  491. return result;
  492. }
  493. public int newUTF8(final String value) {
  494. key.set(UTF8, value, null, null);
  495. Item result = get(key);
  496. if (result == null) {
  497. pool.putByte(UTF8).putUTF8(value);
  498. result = new Item(index++, key);
  499. put(result);
  500. }
  501. return result.index;
  502. }
  503. Item newClassItem(final String value) {
  504. key2.set(CLASS, value, null, null);
  505. Item result = get(key2);
  506. if (result == null) {
  507. pool.put12(CLASS, newUTF8(value));
  508. result = new Item(index++, key2);
  509. put(result);
  510. }
  511. return result;
  512. }
  513. public int newClass(final String value) {
  514. return newClassItem(value).index;
  515. }
  516. /**
  517. * Adds a field reference to the constant pool of the class being build. Does nothing if the constant pool already
  518. * contains a similar item.
  519. *
  520. * @param owner the internal name of the field's owner class.
  521. * @param name the field's name.
  522. * @param desc the field's descriptor.
  523. * @return a new or already existing field reference item.
  524. */
  525. Item newFieldItem(final String owner, final String name, final String desc) {
  526. key3.set(FIELD, owner, name, desc);
  527. Item result = get(key3);
  528. if (result == null) {
  529. put122(FIELD, newClass(owner), newNameType(name, desc));
  530. result = new Item(index++, key3);
  531. put(result);
  532. }
  533. return result;
  534. }
  535. /**
  536. * Adds a method reference to the constant pool of the class being build. Does nothing if the constant pool already
  537. * contains a similar item.
  538. *
  539. * @param owner the internal name of the method's owner class.
  540. * @param name the method's name.
  541. * @param desc the method's descriptor.
  542. * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
  543. * @return a new or already existing method reference item.
  544. */
  545. Item newMethodItem(final String owner, final String name, final String desc, final boolean itf) {
  546. int type = itf ? IMETH : METH;
  547. key3.set(type, owner, name, desc);
  548. Item result = get(key3);
  549. if (result == null) {
  550. put122(type, newClass(owner), newNameType(name, desc));
  551. result = new Item(index++, key3);
  552. put(result);
  553. }
  554. return result;
  555. }
  556. /**
  557. * Adds a string to the constant pool of the class being build. Does nothing if the constant pool already contains a
  558. * similar item.
  559. *
  560. * @param value the String value.
  561. * @return a new or already existing string item.
  562. */
  563. private Item newString(final String value) {
  564. key2.set(STR, value, null, null);
  565. Item result = get(key2);
  566. if (result == null) {
  567. pool.put12(STR, newUTF8(value));
  568. result = new Item(index++, key2);
  569. put(result);
  570. }
  571. return result;
  572. }
  573. public int newNameType(final String name, final String desc) {
  574. return newNameTypeItem(name, desc).index;
  575. }
  576. /**
  577. * Adds a name and type to the constant pool of the class being build. Does nothing if the constant pool already
  578. * contains a similar item.
  579. *
  580. * @param name a name.
  581. * @param desc a type descriptor.
  582. * @return a new or already existing name and type item.
  583. */
  584. Item newNameTypeItem(final String name, final String desc) {
  585. key2.set(NAME_TYPE, name, desc, null);
  586. Item result = get(key2);
  587. if (result == null) {
  588. put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
  589. result = new Item(index++, key2);
  590. put(result);
  591. }
  592. return result;
  593. }
  594. /**
  595. * Returns the constant pool's hash table item which is equal to the given item.
  596. *
  597. * @param key a constant pool item.
  598. * @return the constant pool's hash table item which is equal to the given item, or <tt>null</tt> if there is no
  599. * such item.
  600. */
  601. private Item get(final Item key) {
  602. Item i = items[key.hashCode % items.length];
  603. while (i != null && (i.type != key.type || !key.isEqualTo(i))) {
  604. i = i.next;
  605. }
  606. return i;
  607. }
  608. /**
  609. * Puts the given item in the constant pool's hash table. The hash table <i>must</i> not already contains this item.
  610. *
  611. * @param i the item to be added to the constant pool's hash table.
  612. */
  613. private void put(final Item i) {
  614. if (index > threshold) {
  615. int ll = items.length;
  616. int nl = ll * 2 + 1;
  617. Item[] newItems = new Item[nl];
  618. for (int l = ll - 1; l >= 0; --l) {
  619. Item j = items[l];
  620. while (j != null) {
  621. int index = j.hashCode % newItems.length;
  622. Item k = j.next;
  623. j.next = newItems[index];
  624. newItems[index] = j;
  625. j = k;
  626. }
  627. }
  628. items = newItems;
  629. threshold = (int) (nl * 0.75);
  630. }
  631. int index = i.hashCode % items.length;
  632. i.next = items[index];
  633. items[index] = i;
  634. }
  635. /**
  636. * Puts one byte and two shorts into the constant pool.
  637. *
  638. * @param b a byte.
  639. * @param s1 a short.
  640. * @param s2 another short.
  641. */
  642. private void put122(final int b, final int s1, final int s2) {
  643. pool.put12(b, s1).putShort(s2);
  644. }
  645. }