blob: bb8ccc72680a03c957a4e493336bbaf591239d42 [file] [log] [blame]
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TraceLoggingTypes_h
#define TraceLoggingTypes_h
#include "jsalloc.h"
#include "jsstr.h"
#define TRACELOGGER_TREE_ITEMS(_) \
_(AnnotateScripts) \
_(Baseline) \
_(BaselineCompilation) \
_(Engine) \
_(GC) \
_(GCAllocation) \
_(GCSweeping) \
_(Internal) \
_(Interpreter) \
_(InlinedScripts) \
_(IonCompilation) \
_(IonCompilationPaused) \
_(IonLinking) \
_(IonMonkey) \
_(IrregexpCompile) \
_(IrregexpExecute) \
_(MinorGC) \
_(ParserCompileFunction) \
_(ParserCompileLazy) \
_(ParserCompileScript) \
_(ParserCompileModule) \
_(Scripts) \
_(VM) \
\
/* Specific passes during ion compilation */ \
_(PruneUnusedBranches) \
_(FoldTests) \
_(SplitCriticalEdges) \
_(RenumberBlocks) \
_(ScalarReplacement) \
_(DominatorTree) \
_(PhiAnalysis) \
_(MakeLoopsContiguous) \
_(ApplyTypes) \
_(EagerSimdUnbox) \
_(AliasAnalysis) \
_(GVN) \
_(LICM) \
_(Sincos) \
_(RangeAnalysis) \
_(LoopUnrolling) \
_(EffectiveAddressAnalysis) \
_(AlignmentMaskAnalysis) \
_(EliminateDeadCode) \
_(ReorderInstructions) \
_(EdgeCaseAnalysis) \
_(EliminateRedundantChecks) \
_(AddKeepAliveInstructions) \
_(GenerateLIR) \
_(RegisterAllocation) \
_(GenerateCode)
#define TRACELOGGER_LOG_ITEMS(_) \
_(Bailout) \
_(Invalidation) \
_(Disable) \
_(Enable) \
_(Stop)
// Predefined IDs for common operations. These IDs can be used
// without using TraceLogCreateTextId, because there are already created.
enum TraceLoggerTextId {
TraceLogger_Error = 0,
#define DEFINE_TEXT_ID(textId) TraceLogger_ ## textId,
TRACELOGGER_TREE_ITEMS(DEFINE_TEXT_ID)
TraceLogger_LastTreeItem,
TRACELOGGER_LOG_ITEMS(DEFINE_TEXT_ID)
#undef DEFINE_TEXT_ID
TraceLogger_Last
};
inline const char*
TLTextIdString(TraceLoggerTextId id)
{
switch (id) {
case TraceLogger_Error:
return "TraceLogger failed to process text";
#define NAME(textId) case TraceLogger_ ## textId: return #textId;
TRACELOGGER_TREE_ITEMS(NAME)
TRACELOGGER_LOG_ITEMS(NAME)
#undef NAME
default:
MOZ_CRASH();
}
}
uint32_t
TLStringToTextId(JSLinearString* str);
inline bool
TLTextIdIsToggable(uint32_t id)
{
if (id == TraceLogger_Error)
return false;
if (id == TraceLogger_Internal)
return false;
if (id == TraceLogger_Stop)
return false;
// Actually never used. But added here so it doesn't show as toggle
if (id == TraceLogger_LastTreeItem)
return false;
if (id == TraceLogger_Last)
return false;
// Cannot toggle the logging of one engine on/off, because at the stop
// event it is sometimes unknown which engine was running.
if (id == TraceLogger_IonMonkey || id == TraceLogger_Baseline || id == TraceLogger_Interpreter)
return false;
return true;
}
inline bool
TLTextIdIsTreeEvent(uint32_t id)
{
// Everything between TraceLogger_Error and TraceLogger_LastTreeItem are tree events and
// atm also every custom event.
return (id > TraceLogger_Error && id < TraceLogger_LastTreeItem) ||
id >= TraceLogger_Last;
}
// The maximum amount of ram memory a continuous space structure can take (in bytes).
static const uint32_t CONTINUOUSSPACE_LIMIT = 200 * 1024 * 1024;
template <class T>
class ContinuousSpace {
T* data_;
uint32_t size_;
uint32_t capacity_;
public:
ContinuousSpace ()
: data_(nullptr)
{ }
bool init() {
capacity_ = 64;
size_ = 0;
data_ = (T*) js_malloc(capacity_ * sizeof(T));
if (!data_)
return false;
return true;
}
~ContinuousSpace()
{
js_free(data_);
data_ = nullptr;
}
T* data() {
return data_;
}
uint32_t capacity() {
return capacity_;
}
uint32_t size() {
return size_;
}
bool empty() {
return size_ == 0;
}
uint32_t lastEntryId() {
MOZ_ASSERT(!empty());
return size_ - 1;
}
T& lastEntry() {
return data()[lastEntryId()];
}
bool hasSpaceForAdd(uint32_t count = 1) {
if (size_ + count <= capacity_)
return true;
return false;
}
bool ensureSpaceBeforeAdd(uint32_t count = 1) {
MOZ_ASSERT(data_);
if (hasSpaceForAdd(count))
return true;
uint32_t nCapacity = capacity_ * 2;
if (size_ + count > nCapacity || nCapacity * sizeof(T) > CONTINUOUSSPACE_LIMIT) {
nCapacity = size_ + count;
// Limit the size of a continuous buffer.
if (nCapacity * sizeof(T) > CONTINUOUSSPACE_LIMIT)
return false;
}
T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
if (!entries)
return false;
data_ = entries;
capacity_ = nCapacity;
return true;
}
T& operator[](size_t i) {
MOZ_ASSERT(i < size_);
return data()[i];
}
void push(T& data) {
MOZ_ASSERT(size_ < capacity_);
data()[size_++] = data;
}
T& pushUninitialized() {
MOZ_ASSERT(size_ < capacity_);
return data()[size_++];
}
void pop() {
MOZ_ASSERT(!empty());
size_--;
}
void clear() {
size_ = 0;
}
};
// The layout of the event log in memory and in the log file.
// Readable by JS using TypedArrays.
struct EventEntry {
uint64_t time;
uint32_t textId;
EventEntry(uint64_t time, uint32_t textId)
: time(time), textId(textId)
{ }
};
#endif /* TraceLoggingTypes_h */