/******************************************************************************* | |
* Copyright (c) 2008, 2010 SAP AG. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* SAP AG - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.mat.parser.internal; | |
import java.io.BufferedReader; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.math.BigInteger; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.logging.Logger; | |
import org.eclipse.mat.SnapshotException; | |
import org.eclipse.mat.collect.ArrayInt; | |
import org.eclipse.mat.collect.HashMapIntObject; | |
import org.eclipse.mat.snapshot.ISnapshot; | |
import org.eclipse.mat.snapshot.model.IThreadStack; | |
import org.eclipse.mat.util.MessageUtil; | |
/* package */class ThreadStackHelper | |
{ | |
private static final Logger logger = Logger.getLogger(ThreadStackHelper.class.getCanonicalName()); | |
/* package */static HashMapIntObject<IThreadStack> loadThreadsData(ISnapshot snapshot) throws SnapshotException | |
{ | |
String fileName = snapshot.getSnapshotInfo().getPrefix() + "threads"; //$NON-NLS-1$ | |
File f = new File(fileName); | |
if (!f.exists()) | |
return null; | |
HashMapIntObject<IThreadStack> threadId2stack = new HashMapIntObject<IThreadStack>(); | |
BufferedReader in = null; | |
try | |
{ | |
in = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); //$NON-NLS-1$ | |
String line = in.readLine(); | |
while (line != null) | |
{ | |
line = line.trim(); | |
if (line.startsWith("Thread")) //$NON-NLS-1$ | |
{ | |
long threadAddress = readThreadAddres(line); | |
List<String> lines = new ArrayList<String>(); | |
HashMapIntObject<ArrayInt> line2locals = new HashMapIntObject<ArrayInt>(); | |
line = in.readLine(); | |
while (line != null && !line.equals("")) //$NON-NLS-1$ | |
{ | |
lines.add(line.trim()); | |
line = in.readLine(); | |
} | |
line = in.readLine(); | |
if (line != null && line.trim().startsWith("locals")) //$NON-NLS-1$ | |
{ | |
line = in.readLine(); | |
while (line != null && !line.equals("")) //$NON-NLS-1$ | |
{ | |
int lineNr = readLineNumber(line); | |
if (lineNr >= 0) | |
{ | |
int objectId = readLocalId(line, snapshot); | |
ArrayInt arr = line2locals.get(lineNr); | |
if (arr == null) | |
{ | |
arr = new ArrayInt(); | |
line2locals.put(lineNr, arr); | |
} | |
arr.add(objectId); | |
} | |
line = in.readLine(); | |
} | |
} | |
if (threadAddress != -1) | |
{ | |
try | |
{ | |
int threadId = snapshot.mapAddressToId(threadAddress); | |
IThreadStack stack = new ThreadStackImpl(threadId, buildFrames(lines, line2locals)); | |
threadId2stack.put(threadId, stack); | |
} | |
catch (SnapshotException se) | |
{ | |
// See | |
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=520908 | |
logger.severe(MessageUtil.format(Messages.ThreadStackHelper_InvalidThread, | |
"0x" + Long.toHexString(threadAddress), se.getLocalizedMessage())); //$NON-NLS-1$ | |
} | |
} | |
} | |
if (line != null) | |
line = in.readLine(); | |
else | |
break; | |
} | |
} | |
catch (IOException e) | |
{ | |
throw new SnapshotException(e); | |
} | |
finally | |
{ | |
if (in != null) | |
{ | |
try | |
{ | |
in.close(); | |
} | |
catch (Exception ignore) | |
{ | |
// $JL-EXC$ | |
} | |
} | |
} | |
return threadId2stack; | |
} | |
private static long readThreadAddres(String line) | |
{ | |
int start = line.indexOf("0x"); //$NON-NLS-1$ | |
if (start < 0) | |
return -1; | |
return (new BigInteger(line.substring(start + 2), 16)).longValue(); | |
} | |
private static int readLocalId(String line, ISnapshot snapshot) throws SnapshotException | |
{ | |
int start = line.indexOf("0x"); //$NON-NLS-1$ | |
int end = line.indexOf(',', start); | |
long address = (new BigInteger(line.substring(start + 2, end), 16)).longValue(); | |
return snapshot.mapAddressToId(address); | |
} | |
private static int readLineNumber(String line) | |
{ | |
int start = line.indexOf("line="); //$NON-NLS-1$ | |
return Integer.valueOf(line.substring(start + 5)); | |
} | |
private static StackFrameImpl[] buildFrames(List<String> lines, HashMapIntObject<ArrayInt> line2locals) | |
{ | |
int sz = lines.size(); | |
StackFrameImpl[] frames = new StackFrameImpl[sz]; | |
for (int i = 0; i < sz; i++) | |
{ | |
int[] localsIds = null; | |
ArrayInt locals = line2locals.get(i); | |
if (locals != null && locals.size() > 0) | |
{ | |
localsIds = locals.toArray(); | |
} | |
frames[i] = new StackFrameImpl(lines.get(i), localsIds); | |
} | |
return frames; | |
} | |
} |