View | Details | Raw Unified | Return to bug 182359 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java (-5 / +266 lines)
Lines 140-145 Link Here
140
	public int lastEntryPC; // last entry recorded
140
	public int lastEntryPC; // last entry recorded
141
	public int lastAbruptCompletion; // position of last instruction which abrupts completion: goto/return/athrow
141
	public int lastAbruptCompletion; // position of last instruction which abrupts completion: goto/return/athrow
142
	public int[] lineSeparatorPositions;
142
	public int[] lineSeparatorPositions;
143
	// line number of the body start and the body end
144
	public int lineNumberStart;
145
	public int lineNumberEnd;
143
	
146
	
144
	public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
147
	public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
145
	public int maxFieldCount;
148
	public int maxFieldCount;
Lines 5766-5776 Link Here
5766
		// resize the array pcToSourceMap
5769
		// resize the array pcToSourceMap
5767
		System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
5770
		System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
5768
	}
5771
	}
5769
	int lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, 0, lineSeparatorPositions.length-1);
5770
	// lastEntryPC represents the endPC of the lastEntry.
5772
	// lastEntryPC represents the endPC of the lastEntry.
5771
	if (pcToSourceMapSize > 0) {
5773
	if (pcToSourceMapSize > 0) {
5774
		int lineNumber;
5775
		int previousLineNumber = pcToSourceMap[pcToSourceMapSize - 1];
5776
		if (this.lineNumberStart == this.lineNumberEnd) {
5777
			// method on one line
5778
			lineNumber = this.lineNumberStart;
5779
		} else {
5780
			// Check next line number if this is the one we are looking for
5781
			int[] lineSeparatorPositions2 = this.lineSeparatorPositions;
5782
			int length = lineSeparatorPositions2.length;
5783
			if (previousLineNumber == 1) {
5784
				if (sourcePos < lineSeparatorPositions2[0]) {
5785
					lineNumber = 1;
5786
					/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
5787
					   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
5788
					*/	
5789
					if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
5790
						int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5791
						if (insertionIndex != -1) {
5792
							// widen the existing entry
5793
							// we have to figure out if we need to move the last entry at another location to keep a sorted table
5794
							/* First we need to check if at the insertion position there is not an existing entry
5795
							 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
5796
							 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
5797
							 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
5798
							 */
5799
							if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == lineNumber))) {
5800
								if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5801
									System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5802
									pcToSourceMap[insertionIndex++] = startPC;
5803
									pcToSourceMap[insertionIndex] = lineNumber;
5804
								} else {
5805
									pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5806
								}
5807
							}
5808
						}
5809
					}
5810
					lastEntryPC = position;
5811
					return;
5812
				} else if (length == 1 || sourcePos < lineSeparatorPositions2[1]) {
5813
					lineNumber = 2;
5814
					if (startPC <= lastEntryPC) {
5815
						// we forgot to add an entry.
5816
						// search if an existing entry exists for startPC
5817
						int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5818
						if (insertionIndex != -1) {
5819
							// there is no existing entry starting with startPC.
5820
							int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
5821
							/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
5822
								in this case it is relevant to widen this entry instead of creating a new one.
5823
								line1: this(a,
5824
								  b,
5825
								  c);
5826
								with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5827
								aload0 bytecode. The first entry is the one for the argument a.
5828
								But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5829
								So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5830
							*/
5831
							if (existingEntryIndex != -1) {
5832
								// widen existing entry
5833
								pcToSourceMap[existingEntryIndex] = startPC;
5834
							} else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != lineNumber) {
5835
								// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5836
								System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5837
								pcToSourceMap[insertionIndex++] = startPC;
5838
								pcToSourceMap[insertionIndex] = lineNumber;
5839
								pcToSourceMapSize += 2;
5840
							}
5841
						} else if (position != lastEntryPC) { // no bytecode since last entry pc
5842
							if (lastEntryPC == startPC || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
5843
								pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5844
							} else {
5845
								pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5846
								pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5847
							}
5848
						} else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber && widen) {
5849
							// see if we can widen the existing entry
5850
							pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5851
						}
5852
					} else {
5853
						// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5854
						pcToSourceMap[pcToSourceMapSize++] = startPC;
5855
						pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5856
					}
5857
					lastEntryPC = position;
5858
					return;
5859
				} else {
5860
					// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
5861
					lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
5862
				}
5863
			} else if (previousLineNumber < length) {
5864
				if (lineSeparatorPositions2[previousLineNumber - 2] < sourcePos) {
5865
					if (sourcePos < lineSeparatorPositions2[previousLineNumber - 1]) {
5866
						lineNumber = previousLineNumber;
5867
						/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
5868
						   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
5869
						*/	
5870
						if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
5871
							int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5872
							if (insertionIndex != -1) {
5873
								// widen the existing entry
5874
								// we have to figure out if we need to move the last entry at another location to keep a sorted table
5875
								/* First we need to check if at the insertion position there is not an existing entry
5876
								 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
5877
								 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
5878
								 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
5879
								 */
5880
								if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == lineNumber))) {
5881
									if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5882
										System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5883
										pcToSourceMap[insertionIndex++] = startPC;
5884
										pcToSourceMap[insertionIndex] = lineNumber;
5885
									} else {
5886
										pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5887
									}
5888
								}
5889
							}
5890
						}
5891
						lastEntryPC = position;
5892
						return;
5893
					} else if (sourcePos < lineSeparatorPositions2[previousLineNumber]) {
5894
						lineNumber = previousLineNumber + 1;
5895
						if (startPC <= lastEntryPC) {
5896
							// we forgot to add an entry.
5897
							// search if an existing entry exists for startPC
5898
							int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5899
							if (insertionIndex != -1) {
5900
								// there is no existing entry starting with startPC.
5901
								int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
5902
								/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
5903
									in this case it is relevant to widen this entry instead of creating a new one.
5904
									line1: this(a,
5905
									  b,
5906
									  c);
5907
									with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5908
									aload0 bytecode. The first entry is the one for the argument a.
5909
									But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5910
									So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5911
								*/
5912
								if (existingEntryIndex != -1) {
5913
									// widen existing entry
5914
									pcToSourceMap[existingEntryIndex] = startPC;
5915
								} else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != lineNumber) {
5916
									// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5917
									System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5918
									pcToSourceMap[insertionIndex++] = startPC;
5919
									pcToSourceMap[insertionIndex] = lineNumber;
5920
									pcToSourceMapSize += 2;
5921
								}
5922
							} else if (position != lastEntryPC) { // no bytecode since last entry pc
5923
								if (lastEntryPC == startPC || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
5924
									pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5925
								} else {
5926
									pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5927
									pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5928
								}
5929
							} else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber && widen) {
5930
								// see if we can widen the existing entry
5931
								pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5932
							}
5933
						} else {
5934
							// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5935
							pcToSourceMap[pcToSourceMapSize++] = startPC;
5936
							pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5937
						}
5938
						lastEntryPC = position;
5939
						return;
5940
					} else {
5941
						// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
5942
						lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
5943
					}
5944
				} else {
5945
					// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
5946
					lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
5947
				}
5948
			} else if (lineSeparatorPositions2[length - 1] < sourcePos) {
5949
				lineNumber = length + 1;
5950
				if (startPC <= lastEntryPC) {
5951
					// we forgot to add an entry.
5952
					// search if an existing entry exists for startPC
5953
					int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5954
					if (insertionIndex != -1) {
5955
						// there is no existing entry starting with startPC.
5956
						int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
5957
						/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
5958
							in this case it is relevant to widen this entry instead of creating a new one.
5959
							line1: this(a,
5960
							  b,
5961
							  c);
5962
							with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5963
							aload0 bytecode. The first entry is the one for the argument a.
5964
							But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5965
							So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5966
						*/
5967
						if (existingEntryIndex != -1) {
5968
							// widen existing entry
5969
							pcToSourceMap[existingEntryIndex] = startPC;
5970
						} else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != lineNumber) {
5971
							// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5972
							System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5973
							pcToSourceMap[insertionIndex++] = startPC;
5974
							pcToSourceMap[insertionIndex] = lineNumber;
5975
							pcToSourceMapSize += 2;
5976
						}
5977
					} else if (position != lastEntryPC) { // no bytecode since last entry pc
5978
						if (lastEntryPC == startPC || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
5979
							pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5980
						} else {
5981
							pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5982
							pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5983
						}
5984
					} else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber && widen) {
5985
						// see if we can widen the existing entry
5986
						pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5987
					}
5988
				} else {
5989
					// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5990
					pcToSourceMap[pcToSourceMapSize++] = startPC;
5991
					pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5992
				}
5993
				lastEntryPC = position;
5994
				return;
5995
			} else {
5996
				// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
5997
				lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
5998
			}
5999
		}
5772
		// in this case there is already an entry in the table
6000
		// in this case there is already an entry in the table
5773
		if (pcToSourceMap[pcToSourceMapSize - 1] != lineNumber) {
6001
		if (previousLineNumber != lineNumber) {
5774
			if (startPC <= lastEntryPC) {
6002
			if (startPC <= lastEntryPC) {
5775
				// we forgot to add an entry.
6003
				// we forgot to add an entry.
5776
				// search if an existing entry exists for startPC
6004
				// search if an existing entry exists for startPC
Lines 5832-5838 Link Here
5832
						if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
6060
						if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5833
							System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
6061
							System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5834
							pcToSourceMap[insertionIndex++] = startPC;
6062
							pcToSourceMap[insertionIndex++] = startPC;
5835
							pcToSourceMap[insertionIndex] = lineNumber;						
6063
							pcToSourceMap[insertionIndex] = lineNumber;
5836
						} else {
6064
						} else {
5837
							pcToSourceMap[pcToSourceMapSize - 2] = startPC;
6065
							pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5838
						}
6066
						}
Lines 5842-5847 Link Here
5842
		}
6070
		}
5843
		lastEntryPC = position;
6071
		lastEntryPC = position;
5844
	} else {
6072
	} else {
6073
		int lineNumber = 0;
6074
		if (this.lineNumberStart == this.lineNumberEnd) {
6075
			// method on one line
6076
			lineNumber = this.lineNumberStart;
6077
		} else {
6078
			// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
6079
			lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
6080
		}
5845
		// record the first entry
6081
		// record the first entry
5846
		pcToSourceMap[pcToSourceMapSize++] = startPC;
6082
		pcToSourceMap[pcToSourceMapSize++] = startPC;
5847
		pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6083
		pcToSourceMap[pcToSourceMapSize++] = lineNumber;
Lines 5892-5905 Link Here
5892
public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
6128
public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
5893
	init(targetClassFile);
6129
	init(targetClassFile);
5894
	this.methodDeclaration = referenceMethod;
6130
	this.methodDeclaration = referenceMethod;
6131
	int[] lineSeparatorPositions2 = this.lineSeparatorPositions;
6132
	if (lineSeparatorPositions2 != null) {
6133
		int length = lineSeparatorPositions2.length;
6134
		int lineSeparatorPositionsEnd = length - 1;
6135
		if (referenceMethod.isClinit()
6136
				|| referenceMethod.isConstructor()) {
6137
			this.lineNumberStart = 1;
6138
			this.lineNumberEnd = length == 0 ? 1 : length;
6139
		} else {
6140
			int start = Util.getLineNumber(referenceMethod.bodyStart, lineSeparatorPositions2, 0, lineSeparatorPositionsEnd);
6141
			this.lineNumberStart = start;
6142
			if (start > lineSeparatorPositionsEnd) {
6143
				this.lineNumberEnd = start;
6144
			} else {
6145
				int end = Util.getLineNumber(referenceMethod.bodyEnd, lineSeparatorPositions2, start - 1, lineSeparatorPositionsEnd);
6146
				if (end >= lineSeparatorPositionsEnd) {
6147
					end = length;
6148
				}
6149
				this.lineNumberEnd = end == 0 ? 1 : end;
6150
			}
6151
		}
6152
	}
5895
	this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
6153
	this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
5896
	initializeMaxLocals(referenceMethod.binding);
6154
	initializeMaxLocals(referenceMethod.binding);
5897
}
6155
}
5898
public void reset(ClassFile givenClassFile) {
6156
public void reset(ClassFile givenClassFile) {
5899
	this.targetLevel = givenClassFile.targetJDK;
6157
	this.targetLevel = givenClassFile.targetJDK;
5900
	this.generateAttributes = givenClassFile.produceAttributes;
6158
	int produceAttributes = givenClassFile.produceAttributes;
5901
	if ((givenClassFile.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
6159
	this.generateAttributes = produceAttributes;
6160
	if ((produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
5902
		this.lineSeparatorPositions = givenClassFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
6161
		this.lineSeparatorPositions = givenClassFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
6162
	} else {
6163
		this.lineSeparatorPositions = null;
5903
	}
6164
	}
5904
}
6165
}
5905
/**
6166
/**

Return to bug 182359