| Index: runtime/vm/token_position.h
|
| diff --git a/runtime/vm/token_position.h b/runtime/vm/token_position.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b36d58af9eed5941e4ad22039eb4d73673a55d68
|
| --- /dev/null
|
| +++ b/runtime/vm/token_position.h
|
| @@ -0,0 +1,204 @@
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +#ifndef VM_TOKEN_POSITION_H_
|
| +#define VM_TOKEN_POSITION_H_
|
| +
|
| +#include "platform/utils.h"
|
| +#include "vm/allocation.h"
|
| +
|
| +namespace dart {
|
| +
|
| +// The token space is organized as follows:
|
| +//
|
| +// Sentinel values start at -1 and move towards negative infinity:
|
| +// kNoSourcePos -> -1
|
| +// ClassifyingTokenPositions 1 -> -1 - 1
|
| +// ClassifyingTokenPositions N -> -1 - N
|
| +//
|
| +// Synthetically created AstNodes are given real source positions but encoded
|
| +// as negative numbers from [kSmiMin32, -1 - N]. For example:
|
| +//
|
| +// A source position of 0 in a synthetic AstNode would be encoded as -2 - N.
|
| +// A source position of 1 in a synthetic AstNode would be encoded as -3 - N.
|
| +//
|
| +// All other AstNodes are given real source positions encoded as positive
|
| +// integers.
|
| +//
|
| +// This organization allows for ~1 billion token positions.
|
| +
|
| +#define SENTINEL_TOKEN_DESCRIPTORS(V) \
|
| + V(NoSource, -1) \
|
| + V(Box, -2) \
|
| + V(ParallelMove, -3) \
|
| + V(TempMove, -4) \
|
| + V(Constant, -5) \
|
| + V(PushArgument, -6) \
|
| + V(ControlFlow, -7) \
|
| + V(Context, -8) \
|
| + V(MethodExtractor, -9) \
|
| + V(Last, -10) // Always keep this at the end.
|
| +
|
| +// A token position representing a debug safe source (real) position,
|
| +// non-debug safe source (synthetic) positions, or a classifying value used
|
| +// by the profiler.
|
| +class TokenPosition {
|
| + public:
|
| + TokenPosition()
|
| + : value_(kNoSource.value()) {
|
| + }
|
| +
|
| + explicit TokenPosition(intptr_t value)
|
| + : value_(value) {
|
| + }
|
| +
|
| + bool operator==(const TokenPosition& b) const {
|
| + return value() == b.value();
|
| + }
|
| +
|
| + bool operator!=(const TokenPosition& b) const {
|
| + return !(*this == b);
|
| + }
|
| +
|
| + bool operator<(const TokenPosition& b) const {
|
| + // TODO(johnmccutchan): Assert that this is a source position.
|
| + return value() < b.value();
|
| + }
|
| +
|
| + bool operator>(const TokenPosition& b) const {
|
| + // TODO(johnmccutchan): Assert that this is a source position.
|
| + return b < *this;
|
| + }
|
| +
|
| + bool operator<=(const TokenPosition& b) {
|
| + // TODO(johnmccutchan): Assert that this is a source position.
|
| + return !(*this > b);
|
| + }
|
| +
|
| + bool operator>=(const TokenPosition& b) {
|
| + // TODO(johnmccutchan): Assert that this is a source position.
|
| + return !(*this < b);
|
| + }
|
| +
|
| + static const intptr_t kMaxSentinelDescriptors = 64;
|
| +
|
| +#define DECLARE_VALUES(name, value) \
|
| + static const TokenPosition k##name;
|
| + SENTINEL_TOKEN_DESCRIPTORS(DECLARE_VALUES);
|
| +#undef DECLARE_VALUES
|
| + static const TokenPosition kMinSource;
|
| + static const TokenPosition kMaxSource;
|
| +
|
| + // Decode from a snapshot.
|
| + static TokenPosition SnapshotDecode(int32_t value);
|
| +
|
| + // Encode for writing into a snapshot.
|
| + int32_t SnapshotEncode();
|
| +
|
| + // Increment the token position.
|
| + TokenPosition Next() {
|
| + ASSERT(IsReal());
|
| + value_++;
|
| + return *this;
|
| + }
|
| +
|
| + // The raw value.
|
| + // TODO(johnmccutchan): Make this private.
|
| + intptr_t value() const {
|
| + return value_;
|
| + }
|
| +
|
| + // Return the source position.
|
| + intptr_t Pos() const {
|
| + if (IsSynthetic()) {
|
| + return FromSynthetic().Pos();
|
| + }
|
| + return value_;
|
| + }
|
| +
|
| + // Token position constants.
|
| + static const intptr_t kNoSourcePos = -1;
|
| + static const intptr_t kMinSourcePos = 0;
|
| + static const intptr_t kMaxSourcePos = kSmiMax32 - kMaxSentinelDescriptors - 2;
|
| +
|
| + // Is |this| a classifying sentinel source position?
|
| + // Classifying positions are used by the profiler to group instructions whose
|
| + // cost isn't naturally attributable to a source location.
|
| + bool IsClassifying() const {
|
| + return (value_ >= kBox.value()) && (value_ <= kLast.value());
|
| + }
|
| +
|
| + // Is |this| the no source position sentinel?
|
| + bool IsNoSource() const {
|
| + return *this == kNoSource;
|
| + }
|
| +
|
| + // Is |this| a synthetic source position?
|
| + // Synthetic source positions are used by the profiler to attribute ticks to a
|
| + // pieces of source, but ignored by the debugger as potential breakpoints.
|
| + bool IsSynthetic() const;
|
| +
|
| + // Is |this| a real source position?
|
| + bool IsReal() const {
|
| + return value_ >= kMinSourcePos;
|
| + }
|
| +
|
| + // Is |this| a source position?
|
| + bool IsSourcePosition() const {
|
| + return IsReal() || IsNoSource() || IsSynthetic();
|
| + }
|
| +
|
| + // Is |this| a debug pause source position?
|
| + bool IsDebugPause() const {
|
| + // Sanity check some values here.
|
| + ASSERT(kNoSource.value() == kNoSourcePos);
|
| + ASSERT(kLast.value() < kNoSource.value());
|
| + ASSERT(kLast.value() > -kMaxSentinelDescriptors);
|
| + return IsReal();
|
| + }
|
| +
|
| + // Convert |this| into a synthetic source position. Sentinel values remain
|
| + // unchanged.
|
| + TokenPosition ToSynthetic() const {
|
| + const intptr_t value = value_;
|
| + if (IsClassifying() || IsNoSource()) {
|
| + return *this;
|
| + }
|
| + if (IsSynthetic()) {
|
| + return *this;
|
| + }
|
| + const TokenPosition synthetic_value =
|
| + TokenPosition((kLast.value() - 1) - value);
|
| + ASSERT(synthetic_value.IsSynthetic());
|
| + ASSERT(synthetic_value.value() < kLast.value());
|
| + return synthetic_value;
|
| + }
|
| +
|
| + // Convert |this| from a synthetic source position. Sentinel values remain
|
| + // unchanged.
|
| + TokenPosition FromSynthetic() const {
|
| + const intptr_t synthetic_value = value_;
|
| + if (IsClassifying() || IsNoSource()) {
|
| + return *this;
|
| + }
|
| + if (!IsSynthetic()) {
|
| + return *this;
|
| + }
|
| + const TokenPosition value =
|
| + TokenPosition(-synthetic_value + (kLast.value() - 1));
|
| + ASSERT(!value.IsSynthetic());
|
| + return value;
|
| + }
|
| +
|
| + const char* ToCString() const;
|
| +
|
| + private:
|
| + int32_t value_;
|
| +
|
| + DISALLOW_ALLOCATION();
|
| +};
|
| +
|
| +} // namespace dart
|
| +
|
| +#endif // VM_TOKEN_POSITION_H_
|
|
|