History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/jdi/ConcreteMethodImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/jdi/ConcreteMethodImpl.java+545−0
@@ -0,0 +1,545 @@
1/*
2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.jdi;
27
28import com.sun.jdi.*;
29
30import java.util.List;
31import java.util.Map;
32import java.util.Iterator;
33import java.util.ListIterator;
34import java.util.HashMap;
35import java.util.ArrayList;
36import java.util.Collections;
37import java.lang.ref.SoftReference;
38
39/**
40 * Represents methods with method bodies.
41 * That is, non-native non-abstract methods.
42 * Private to MethodImpl.
43 */
44public class ConcreteMethodImpl extends MethodImpl {
45
46 /*
47 * A subset of the line number info that is softly cached
48 */
49 static private class SoftLocationXRefs {
50 final String stratumID; // The stratum of this information
51 final Map<Integer, List<Location>> lineMapper; // Maps line number to location(s)
52 final List<Location> lineLocations; // List of locations ordered by code index
53
54 /*
55 * Note: these do not necessarily correspond to
56 * the line numbers of the first and last elements
57 * in the lineLocations list. Use these only for bounds
58 * checking and with lineMapper.
59 */
60 final int lowestLine;
61 final int highestLine;
62
63 SoftLocationXRefs(String stratumID, Map<Integer, List<Location>> lineMapper, List<Location> lineLocations,
64 int lowestLine, int highestLine) {
65 this.stratumID = stratumID;
66 this.lineMapper = Collections.unmodifiableMap(lineMapper);
67 this.lineLocations =
68 Collections.unmodifiableList(lineLocations);
69 this.lowestLine = lowestLine;
70 this.highestLine = highestLine;
71 }
72 }
73
74 private Location location = null;
75 private SoftReference<SoftLocationXRefs> softBaseLocationXRefsRef;
76 private SoftReference<SoftLocationXRefs> softOtherLocationXRefsRef;
77 private SoftReference<List<LocalVariable>> variablesRef = null;
78 private boolean absentVariableInformation = false;
79 private long firstIndex = -1;
80 private long lastIndex = -1;
81 private SoftReference<byte[]> bytecodesRef = null;
82 private int argSlotCount = -1;
83
84 ConcreteMethodImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
85 long ref,
86 String name, String signature,
87 String genericSignature, int modifiers) {
88
89 // The generic signature is set when this is created
90 super(vm, declaringType, ref, name, signature,
91 genericSignature, modifiers);
92 }
93
94 public Location location() {
95 if (location == null) {
96 getBaseLocations();
97 }
98 return location;
99 }
100
101 List<Location> sourceNameFilter(List<Location> list,
102 SDE.Stratum stratum,
103 String sourceName)
104 throws AbsentInformationException {
105 if (sourceName == null) {
106 return list;
107 } else {
108 /* needs sourceName filteration */
109 List<Location> locs = new ArrayList<Location>();
110 for (Location loc : list) {
111 if (((LocationImpl)loc).sourceName(stratum).equals(sourceName)) {
112 locs.add(loc);
113 }
114 }
115 return locs;
116 }
117 }
118
119 List<Location> allLineLocations(SDE.Stratum stratum,
120 String sourceName)
121 throws AbsentInformationException {
122 List<Location> lineLocations = getLocations(stratum).lineLocations;
123
124 if (lineLocations.size() == 0) {
125 throw new AbsentInformationException();
126 }
127
128 return Collections.unmodifiableList(
129 sourceNameFilter(lineLocations, stratum, sourceName));
130 }
131
132 List<Location> locationsOfLine(SDE.Stratum stratum,
133 String sourceName,
134 int lineNumber)
135 throws AbsentInformationException {
136 SoftLocationXRefs info = getLocations(stratum);
137
138 if (info.lineLocations.size() == 0) {
139 throw new AbsentInformationException();
140 }
141
142 /*
143 * Find the locations which match the line number
144 * passed in.
145 */
146 List<Location> list = info.lineMapper.get(new Integer(lineNumber));
147
148 if (list == null) {
149 list = new ArrayList<Location>(0);
150 }
151 return Collections.unmodifiableList(
152 sourceNameFilter(list, stratum, sourceName));
153 }
154
155
156 public Location locationOfCodeIndex(long codeIndex) {
157 if (firstIndex == -1) {
158 getBaseLocations();
159 }
160
161 /*
162 * Check for invalid code index.
163 */
164 if (codeIndex < firstIndex || codeIndex > lastIndex) {
165 return null;
166 }
167
168 return new LocationImpl(virtualMachine(), this, codeIndex);
169 }
170
171
172 LineInfo codeIndexToLineInfo(SDE.Stratum stratum,
173 long codeIndex) {
174 if (firstIndex == -1) {
175 getBaseLocations();
176 }
177
178 /*
179 * Check for invalid code index.
180 */
181 if (codeIndex < firstIndex || codeIndex > lastIndex) {
182 throw new InternalError(
183 "Location with invalid code index");
184 }
185
186 List<Location> lineLocations = getLocations(stratum).lineLocations;
187
188 /*
189 * Check for absent line numbers.
190 */
191 if (lineLocations.size() == 0) {
192 return super.codeIndexToLineInfo(stratum, codeIndex);
193 }
194
195 Iterator iter = lineLocations.iterator();
196 /*
197 * Treat code before the beginning of the first line table
198 * entry as part of the first line. javac will generate
199 * code like this for some local classes. This "prolog"
200 * code contains assignments from locals in the enclosing
201 * scope to synthetic fields in the local class. Same for
202 * other language prolog code.
203 */
204 LocationImpl bestMatch = (LocationImpl)iter.next();
205 while (iter.hasNext()) {
206 LocationImpl current = (LocationImpl)iter.next();
207 if (current.codeIndex() > codeIndex) {
208 break;
209 }
210 bestMatch = current;
211 }
212 return bestMatch.getLineInfo(stratum);
213 }
214
215
216 public List<LocalVariable> variables() throws AbsentInformationException {
217 return getVariables();
218 }
219
220 public List<LocalVariable> variablesByName(String name) throws AbsentInformationException {
221 List<LocalVariable> variables = getVariables();
222
223 List<LocalVariable> retList = new ArrayList<LocalVariable>(2);
224 Iterator iter = variables.iterator();
225 while(iter.hasNext()) {
226 LocalVariable variable = (LocalVariable)iter.next();
227 if (variable.name().equals(name)) {
228 retList.add(variable);
229 }
230 }
231 return retList;
232 }
233
234 public List<LocalVariable> arguments() throws AbsentInformationException {
235 List<LocalVariable> variables = getVariables();
236
237 List<LocalVariable> retList = new ArrayList<LocalVariable>(variables.size());
238 Iterator iter = variables.iterator();
239 while(iter.hasNext()) {
240 LocalVariable variable = (LocalVariable)iter.next();
241 if (variable.isArgument()) {
242 retList.add(variable);
243 }
244 }
245 return retList;
246 }
247
248 public byte[] bytecodes() {
249 byte[] bytecodes = (bytecodesRef == null) ? null :
250 bytecodesRef.get();
251 if (bytecodes == null) {
252 try {
253 bytecodes = JDWP.Method.Bytecodes.
254 process(vm, declaringType, ref).bytes;
255 } catch (JDWPException exc) {
256 throw exc.toJDIException();
257 }
258 bytecodesRef = new SoftReference<byte[]>(bytecodes);
259 }
260 /*
261 * Arrays are always modifiable, so it is a little unsafe
262 * to return the cached bytecodes directly; instead, we
263 * make a clone at the cost of using more memory.
264 */
265 return bytecodes.clone();
266 }
267
268 int argSlotCount() throws AbsentInformationException {
269 if (argSlotCount == -1) {
270 getVariables();
271 }
272 return argSlotCount;
273 }
274
275 private SoftLocationXRefs getLocations(SDE.Stratum stratum) {
276 if (stratum.isJava()) {
277 return getBaseLocations();
278 }
279 String stratumID = stratum.id();
280 SoftLocationXRefs info =
281 (softOtherLocationXRefsRef == null) ? null :
282 softOtherLocationXRefsRef.get();
283 if (info != null && info.stratumID.equals(stratumID)) {
284 return info;
285 }
286
287 List<Location> lineLocations = new ArrayList<Location>();
288 Map<Integer, List<Location>> lineMapper = new HashMap<Integer, List<Location>>();
289 int lowestLine = -1;
290 int highestLine = -1;
291 SDE.LineStratum lastLineStratum = null;
292 SDE.Stratum baseStratum =
293 declaringType.stratum(SDE.BASE_STRATUM_NAME);
294 Iterator it = getBaseLocations().lineLocations.iterator();
295 while(it.hasNext()) {
296 LocationImpl loc = (LocationImpl)it.next();
297 int baseLineNumber = loc.lineNumber(baseStratum);
298 SDE.LineStratum lineStratum =
299 stratum.lineStratum(declaringType,
300 baseLineNumber);
301
302 if (lineStratum == null) {
303 // location not mapped in this stratum
304 continue;
305 }
306
307 int lineNumber = lineStratum.lineNumber();
308
309 // remove unmapped and dup lines
310 if ((lineNumber != -1) &&
311 (!lineStratum.equals(lastLineStratum))) {
312 lastLineStratum = lineStratum;
313
314 // Remember the largest/smallest line number
315 if (lineNumber > highestLine) {
316 highestLine = lineNumber;
317 }
318 if ((lineNumber < lowestLine) || (lowestLine == -1)) {
319 lowestLine = lineNumber;
320 }
321
322 loc.addStratumLineInfo(
323 new StratumLineInfo(stratumID,
324 lineNumber,
325 lineStratum.sourceName(),
326 lineStratum.sourcePath()));
327
328 // Add to the location list
329 lineLocations.add(loc);
330
331 // Add to the line -> locations map
332 Integer key = new Integer(lineNumber);
333 List<Location> mappedLocs = lineMapper.get(key);
334 if (mappedLocs == null) {
335 mappedLocs = new ArrayList<Location>(1);
336 lineMapper.put(key, mappedLocs);
337 }
338 mappedLocs.add(loc);
339 }
340 }
341
342 info = new SoftLocationXRefs(stratumID,
343 lineMapper, lineLocations,
344 lowestLine, highestLine);
345 softOtherLocationXRefsRef = new SoftReference<SoftLocationXRefs>(info);
346 return info;
347 }
348
349 private SoftLocationXRefs getBaseLocations() {
350 SoftLocationXRefs info = (softBaseLocationXRefsRef == null) ? null :
351 softBaseLocationXRefsRef.get();
352 if (info != null) {
353 return info;
354 }
355
356 JDWP.Method.LineTable lntab = null;
357 try {
358 lntab = JDWP.Method.LineTable.process(vm, declaringType, ref);
359 } catch (JDWPException exc) {
360 /*
361 * Note: the absent info error shouldn't happen here
362 * because the first and last index are always available.
363 */
364 throw exc.toJDIException();
365 }
366
367 int count = lntab.lines.length;
368
369 List<Location> lineLocations = new ArrayList<Location>(count);
370 Map<Integer, List<Location>>lineMapper = new HashMap<Integer, List<Location>>();
371 int lowestLine = -1;
372 int highestLine = -1;
373 for (int i = 0; i < count; i++) {
374 long bci = lntab.lines[i].lineCodeIndex;
375 int lineNumber = lntab.lines[i].lineNumber;
376
377 /*
378 * Some compilers will point multiple consecutive
379 * lines at the same location. We need to choose
380 * one of them so that we can consistently map back
381 * and forth between line and location. So we choose
382 * to record only the last line entry at a particular
383 * location.
384 */
385 if ((i + 1 == count) || (bci != lntab.lines[i+1].lineCodeIndex)) {
386 // Remember the largest/smallest line number
387 if (lineNumber > highestLine) {
388 highestLine = lineNumber;
389 }
390 if ((lineNumber < lowestLine) || (lowestLine == -1)) {
391 lowestLine = lineNumber;
392 }
393 LocationImpl loc =
394 new LocationImpl(virtualMachine(), this, bci);
395 loc.addBaseLineInfo(
396 new BaseLineInfo(lineNumber, declaringType));
397
398 // Add to the location list
399 lineLocations.add(loc);
400
401 // Add to the line -> locations map
402 Integer key = new Integer(lineNumber);
403 List<Location> mappedLocs = lineMapper.get(key);
404 if (mappedLocs == null) {
405 mappedLocs = new ArrayList<Location>(1);
406 lineMapper.put(key, mappedLocs);
407 }
408 mappedLocs.add(loc);
409 }
410 }
411
412 /*
413 * firstIndex, lastIndex, and startLocation need to be
414 * retrieved only once since they are strongly referenced.
415 */
416 if (location == null) {
417 firstIndex = lntab.start;
418 lastIndex = lntab.end;
419 /*
420 * The startLocation is the first one in the
421 * location list if we have one;
422 * otherwise, we construct a location for a
423 * method start with no line info
424 */
425 if (count > 0) {
426 location = lineLocations.get(0);
427 } else {
428 location = new LocationImpl(virtualMachine(), this,
429 firstIndex);
430 }
431 }
432
433 info = new SoftLocationXRefs(SDE.BASE_STRATUM_NAME,
434 lineMapper, lineLocations,
435 lowestLine, highestLine);
436 softBaseLocationXRefsRef = new SoftReference<SoftLocationXRefs>(info);
437 return info;
438 }
439
440 private List<LocalVariable> getVariables1_4() throws AbsentInformationException {
441 JDWP.Method.VariableTable vartab = null;
442 try {
443 vartab = JDWP.Method.VariableTable.
444 process(vm, declaringType, ref);
445 } catch (JDWPException exc) {
446 if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
447 absentVariableInformation = true;
448 throw new AbsentInformationException();
449 } else {
450 throw exc.toJDIException();
451 }
452 }
453
454 // Get the number of slots used by argument variables
455 argSlotCount = vartab.argCnt;
456 int count = vartab.slots.length;
457 List<LocalVariable> variables = new ArrayList<LocalVariable>(count);
458 for (int i=0; i<count; i++) {
459 JDWP.Method.VariableTable.SlotInfo si = vartab.slots[i];
460
461 /*
462 * Skip "this*" entries because they are never real
463 * variables from the JLS perspective.
464 */
465 if (!si.name.startsWith("this$") && !si.name.equals("this")) {
466 Location scopeStart = new LocationImpl(virtualMachine(),
467 this, si.codeIndex);
468 Location scopeEnd =
469 new LocationImpl(virtualMachine(), this,
470 si.codeIndex + si.length - 1);
471 LocalVariable variable =
472 new LocalVariableImpl(virtualMachine(), this,
473 si.slot, scopeStart, scopeEnd,
474 si.name, si.signature, null);
475 // Add to the variable list
476 variables.add(variable);
477 }
478 }
479 return variables;
480 }
481
482 private List<LocalVariable> getVariables1() throws AbsentInformationException {
483
484 if (!vm.canGet1_5LanguageFeatures()) {
485 return getVariables1_4();
486 }
487
488 JDWP.Method.VariableTableWithGeneric vartab = null;
489 try {
490 vartab = JDWP.Method.VariableTableWithGeneric.
491 process(vm, declaringType, ref);
492 } catch (JDWPException exc) {
493 if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
494 absentVariableInformation = true;
495 throw new AbsentInformationException();
496 } else {
497 throw exc.toJDIException();
498 }
499 }
500
501 // Get the number of slots used by argument variables
502 argSlotCount = vartab.argCnt;
503 int count = vartab.slots.length;
504 List<LocalVariable> variables = new ArrayList<LocalVariable>(count);
505 for (int i=0; i<count; i++) {
506 JDWP.Method.VariableTableWithGeneric.SlotInfo si = vartab.slots[i];
507
508 /*
509 * Skip "this*" entries because they are never real
510 * variables from the JLS perspective.
511 */
512 if (!si.name.startsWith("this$") && !si.name.equals("this")) {
513 Location scopeStart = new LocationImpl(virtualMachine(),
514 this, si.codeIndex);
515 Location scopeEnd =
516 new LocationImpl(virtualMachine(), this,
517 si.codeIndex + si.length - 1);
518 LocalVariable variable =
519 new LocalVariableImpl(virtualMachine(), this,
520 si.slot, scopeStart, scopeEnd,
521 si.name, si.signature,
522 si.genericSignature);
523 // Add to the variable list
524 variables.add(variable);
525 }
526 }
527 return variables;
528 }
529
530 private List<LocalVariable> getVariables() throws AbsentInformationException {
531 if (absentVariableInformation) {
532 throw new AbsentInformationException();
533 }
534
535 List<LocalVariable> variables = (variablesRef == null) ? null :
536 variablesRef.get();
537 if (variables != null) {
538 return variables;
539 }
540 variables = getVariables1();
541 variables = Collections.unmodifiableList(variables);
542 variablesRef = new SoftReference<List<LocalVariable>>(variables);
543 return variables;
544 }
545}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t