View | Details | Raw Unified | Return to bug 86813
Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java (+7 lines)
Lines 163-168 Link Here
163
			
163
			
164
			// generate the switch block statements
164
			// generate the switch block statements
165
			int caseIndex = 0;
165
			int caseIndex = 0;
166
			int pcBeforeLastStatement = codeStream.position;
166
			if (this.statements != null) {
167
			if (this.statements != null) {
167
				for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) {
168
				for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) {
168
					Statement statement = this.statements[i];
169
					Statement statement = this.statements[i];
Lines 180-192 Link Here
180
							}
181
							}
181
						}
182
						}
182
					}
183
					}
184
					pcBeforeLastStatement = codeStream.position;
183
					statement.generateCode(scope, codeStream);
185
					statement.generateCode(scope, codeStream);
184
				}
186
				}
185
			}
187
			}
186
			// place the trailing labels (for break and default case)
188
			// place the trailing labels (for break and default case)
189
			int pcToSourceMapSize = codeStream.pcToSourceMapSize;
187
			this.breakLabel.place();
190
			this.breakLabel.place();
188
			if (defaultCase == null) {
191
			if (defaultCase == null) {
189
				defaultLabel.place();
192
				defaultLabel.place();
193
			}
194
			if (pcToSourceMapSize != codeStream.pcToSourceMapSize) {
195
				// optimize goto next bytecode
196
				codeStream.recordPositionsFrom(pcBeforeLastStatement, this.sourceEnd, true);
190
			}
197
			}
191
			// May loose some local variable initializations : affecting the local variable attributes
198
			// May loose some local variable initializations : affecting the local variable attributes
192
			if (mergedInitStateIndex != -1) {
199
			if (mergedInitStateIndex != -1) {
(-)compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java (+97 lines)
Lines 5364-5369 Link Here
5364
		lastEntryPC = position;
5364
		lastEntryPC = position;
5365
	}
5365
	}
5366
}
5366
}
5367
public void recordPositionsFrom(int startPC, int sourcePos, boolean alwaysInsert) {
5368
5369
	/* Record positions in the table, only if nothing has 
5370
	 * already been recorded. Since we output them on the way 
5371
	 * up (children first for more specific info)
5372
	 * The pcToSourceMap table is always sorted.
5373
	 */
5374
5375
	if (!generateLineNumberAttributes)
5376
		return;
5377
	if (sourcePos == 0)
5378
		return;
5379
5380
	// no code generated for this node. e.g. field without any initialization
5381
	if (!alwaysInsert && position == startPC)
5382
		return;
5383
5384
	// Widening an existing entry that already has the same source positions
5385
	if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
5386
		// resize the array pcToSourceMap
5387
		System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
5388
	}
5389
	int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, sourcePos);
5390
	// lastEntryPC represents the endPC of the lastEntry.
5391
	if (pcToSourceMapSize > 0) {
5392
		// in this case there is already an entry in the table
5393
		if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
5394
			if (startPC < lastEntryPC) {
5395
				// we forgot to add an entry.
5396
				// search if an existing entry exists for startPC
5397
				int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5398
				if (insertionIndex != -1) {
5399
					// there is no existing entry starting with startPC.
5400
					int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
5401
					/* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
5402
						in this case it is relevant to widen this entry instead of creating a new one.
5403
						line1: this(a,
5404
						  b,
5405
						  c);
5406
						with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5407
						aload0 bytecode. The first entry is the one for the argument a.
5408
						But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5409
						So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5410
					*/
5411
					if (existingEntryIndex != -1) {
5412
						// widen existing entry
5413
						pcToSourceMap[existingEntryIndex] = startPC;
5414
					} else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != newLine) {
5415
						// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5416
						System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5417
						pcToSourceMap[insertionIndex++] = startPC;
5418
						pcToSourceMap[insertionIndex] = newLine;
5419
						pcToSourceMapSize += 2;
5420
					}
5421
				} else if (position != lastEntryPC) { // no bytecode since last entry pc
5422
					pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5423
					pcToSourceMap[pcToSourceMapSize++] = newLine;
5424
				}
5425
			} else {
5426
				// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5427
				pcToSourceMap[pcToSourceMapSize++] = startPC;
5428
				pcToSourceMap[pcToSourceMapSize++] = newLine;
5429
			}
5430
		} else {
5431
			/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
5432
			   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
5433
			*/	
5434
			if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
5435
				int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5436
				if (insertionIndex != -1) {
5437
					// widen the existing entry
5438
					// we have to figure out if we need to move the last entry at another location to keep a sorted table
5439
					/* First we need to check if at the insertion position there is not an existing entry
5440
					 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
5441
					 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
5442
					 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
5443
					 */
5444
					if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == newLine))) {
5445
						if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5446
							System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5447
							pcToSourceMap[insertionIndex++] = startPC;
5448
							pcToSourceMap[insertionIndex] = newLine;						
5449
						} else {
5450
							pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5451
						}
5452
					}
5453
				}
5454
			}
5455
		}
5456
		lastEntryPC = position;
5457
	} else {
5458
		// record the first entry
5459
		pcToSourceMap[pcToSourceMapSize++] = startPC;
5460
		pcToSourceMap[pcToSourceMapSize++] = newLine;
5461
		lastEntryPC = position;
5462
	}
5463
}
5367
/**
5464
/**
5368
 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
5465
 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
5369
 */
5466
 */

Return to bug 86813