blob: 2e40ad465a6e49805a4ed2fabf49b91d00f12443 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Class object pool
*/
#include "hprof.h"
#include "object.h"
#include "logging.h"
#include "unordered_set.h"
namespace art {
namespace hprof {
typedef std::tr1::unordered_set<Class*, ObjectIdentityHash> ClassSet;
typedef std::tr1::unordered_set<Class*, ObjectIdentityHash>::iterator ClassSetIterator;
static Mutex classes_lock_("hprof classes");
static ClassSet classes_;
int hprofStartup_Class() {
return 0;
}
int hprofShutdown_Class() {
return 0;
}
static int getPrettyClassNameId(Class* clazz) {
return hprofLookupStringId(PrettyClass(clazz));
}
hprof_class_object_id hprofLookupClassId(Class* clazz) {
if (clazz == NULL) {
/* Someone's probably looking up the superclass
* of java.lang.Object or of a primitive class.
*/
return (hprof_class_object_id)0;
}
MutexLock mu(classes_lock_);
std::pair<ClassSetIterator, bool> result = classes_.insert(clazz);
Class* present = *result.first;
/* Make sure that the class's name is in the string table.
* This is a bunch of extra work that we only have to do
* because of the order of tables in the output file
* (strings need to be dumped before classes).
*/
getPrettyClassNameId(clazz);
return (hprof_string_id) present;
}
int hprofDumpClasses(hprof_context_t *ctx) {
MutexLock mu(classes_lock_);
hprof_record_t *rec = &ctx->curRec;
uint32_t nextSerialNumber = 1;
for (ClassSetIterator it = classes_.begin(); it != classes_.end(); ++it) {
Class* clazz = *it;
CHECK(clazz != NULL);
int err = hprofStartNewRecord(ctx, HPROF_TAG_LOAD_CLASS, HPROF_TIME);
if (err != 0) {
return err;
}
/* LOAD CLASS format:
*
* uint32_t: class serial number (always > 0)
* ID: class object ID
* uint32_t: stack trace serial number
* ID: class name string ID
*
* We use the address of the class object structure as its ID.
*/
hprofAddU4ToRecord(rec, nextSerialNumber++);
hprofAddIdToRecord(rec, (hprof_class_object_id) clazz);
hprofAddU4ToRecord(rec, HPROF_NULL_STACK_TRACE);
hprofAddIdToRecord(rec, getPrettyClassNameId(clazz));
}
return 0;
}
} // namespace hprof
} // namespace art