[objects] Extract DebugInfo and BreakPointInfo to own file
BUG=v8:5402 Review-Url: https://codereview.chromium.org/2900713004 Cr-Commit-Position: refs/heads/master@{#45486}
This commit is contained in:
parent
9dbafbd5d3
commit
d74ece4180
3
BUILD.gn
3
BUILD.gn
@ -1748,6 +1748,9 @@ v8_source_set("v8_base") {
|
||||
"src/objects/code-cache.h",
|
||||
"src/objects/compilation-cache-inl.h",
|
||||
"src/objects/compilation-cache.h",
|
||||
"src/objects/debug-objects-inl.h",
|
||||
"src/objects/debug-objects.cc",
|
||||
"src/objects/debug-objects.h",
|
||||
"src/objects/descriptor-array.h",
|
||||
"src/objects/dictionary.h",
|
||||
"src/objects/frame-array-inl.h",
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "src/list.h"
|
||||
#include "src/log.h"
|
||||
#include "src/messages.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/snapshot/natives.h"
|
||||
#include "src/wasm/wasm-module.h"
|
||||
#include "src/wasm/wasm-objects.h"
|
||||
@ -248,6 +249,11 @@ void CodeBreakIterator::SkipToPosition(int position,
|
||||
SkipTo(it.BreakIndexFromPosition(position, alignment));
|
||||
}
|
||||
|
||||
int CodeBreakIterator::code_offset() {
|
||||
return static_cast<int>(rinfo()->pc() -
|
||||
debug_info_->DebugCode()->instruction_start());
|
||||
}
|
||||
|
||||
void CodeBreakIterator::SetDebugBreak() {
|
||||
DebugBreakType debug_break_type = GetDebugBreakType();
|
||||
DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "src/flags.h"
|
||||
#include "src/frames.h"
|
||||
#include "src/globals.h"
|
||||
#include "src/objects/debug-objects.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
#include "src/source-position-table.h"
|
||||
#include "src/string-stream.h"
|
||||
@ -177,10 +178,7 @@ class CodeBreakIterator : public BreakIterator {
|
||||
|
||||
void SkipToPosition(int position, BreakPositionAlignment alignment);
|
||||
|
||||
int code_offset() override {
|
||||
return static_cast<int>(rinfo()->pc() -
|
||||
debug_info_->DebugCode()->instruction_start());
|
||||
}
|
||||
int code_offset() override;
|
||||
|
||||
private:
|
||||
int GetModeMask();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "src/global-handles.h"
|
||||
#include "src/interpreter/interpreter.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/tracing/trace-event.h"
|
||||
#include "src/v8.h"
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/conversions.h"
|
||||
#include "src/isolate-inl.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/frame-array-inl.h"
|
||||
#include "src/objects/module-info.h"
|
||||
#include "src/objects/scope-info.h"
|
||||
|
@ -17,8 +17,10 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class BreakPointInfo;
|
||||
class BoilerplateDescription;
|
||||
class ConstantElementsPair;
|
||||
class DebugInfo;
|
||||
|
||||
enum FunctionMode {
|
||||
// With prototype.
|
||||
|
@ -338,6 +338,12 @@ using v8::MemoryPressureLevel;
|
||||
V(WithContextMap) \
|
||||
PRIVATE_SYMBOL_LIST(V)
|
||||
|
||||
#define FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(heap, array, start, length) \
|
||||
do { \
|
||||
heap->RecordFixedArrayElements(array, start, length); \
|
||||
heap->incremental_marking()->IterateBlackObject(array); \
|
||||
} while (false)
|
||||
|
||||
// Forward declarations.
|
||||
class AllocationObserver;
|
||||
class ArrayBufferTracker;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/layout-descriptor.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/literal-objects.h"
|
||||
#include "src/objects/module-info.h"
|
||||
#include "src/ostreams.h"
|
||||
|
@ -67,79 +67,6 @@ int PropertyDetails::field_width_in_words() const {
|
||||
return representation().IsDouble() ? kDoubleSize / kPointerSize : 1;
|
||||
}
|
||||
|
||||
#define INT_ACCESSORS(holder, name, offset) \
|
||||
int holder::name() const { return READ_INT_FIELD(this, offset); } \
|
||||
void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
|
||||
|
||||
#define ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
|
||||
set_condition) \
|
||||
type* holder::name() const { \
|
||||
DCHECK(get_condition); \
|
||||
return type::cast(READ_FIELD(this, offset)); \
|
||||
} \
|
||||
void holder::set_##name(type* value, WriteBarrierMode mode) { \
|
||||
DCHECK(set_condition); \
|
||||
WRITE_FIELD(this, offset, value); \
|
||||
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
|
||||
}
|
||||
#define ACCESSORS_CHECKED(holder, name, type, offset, condition) \
|
||||
ACCESSORS_CHECKED2(holder, name, type, offset, condition, condition)
|
||||
|
||||
#define ACCESSORS(holder, name, type, offset) \
|
||||
ACCESSORS_CHECKED(holder, name, type, offset, true)
|
||||
|
||||
// Getter that returns a Smi as an int and writes an int as a Smi.
|
||||
#define SMI_ACCESSORS_CHECKED(holder, name, offset, condition) \
|
||||
int holder::name() const { \
|
||||
DCHECK(condition); \
|
||||
Object* value = READ_FIELD(this, offset); \
|
||||
return Smi::cast(value)->value(); \
|
||||
} \
|
||||
void holder::set_##name(int value) { \
|
||||
DCHECK(condition); \
|
||||
WRITE_FIELD(this, offset, Smi::FromInt(value)); \
|
||||
}
|
||||
|
||||
#define SMI_ACCESSORS(holder, name, offset) \
|
||||
SMI_ACCESSORS_CHECKED(holder, name, offset, true)
|
||||
|
||||
#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
|
||||
int holder::synchronized_##name() const { \
|
||||
Object* value = ACQUIRE_READ_FIELD(this, offset); \
|
||||
return Smi::cast(value)->value(); \
|
||||
} \
|
||||
void holder::synchronized_set_##name(int value) { \
|
||||
RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
|
||||
}
|
||||
|
||||
#define NOBARRIER_SMI_ACCESSORS(holder, name, offset) \
|
||||
int holder::nobarrier_##name() const { \
|
||||
Object* value = NOBARRIER_READ_FIELD(this, offset); \
|
||||
return Smi::cast(value)->value(); \
|
||||
} \
|
||||
void holder::nobarrier_set_##name(int value) { \
|
||||
NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
|
||||
}
|
||||
|
||||
#define BOOL_GETTER(holder, field, name, offset) \
|
||||
bool holder::name() const { \
|
||||
return BooleanBit::get(field(), offset); \
|
||||
} \
|
||||
|
||||
|
||||
#define BOOL_ACCESSORS(holder, field, name, offset) \
|
||||
bool holder::name() const { \
|
||||
return BooleanBit::get(field(), offset); \
|
||||
} \
|
||||
void holder::set_##name(bool value) { \
|
||||
set_##field(BooleanBit::set(field(), offset, value)); \
|
||||
}
|
||||
|
||||
#define TYPE_CHECKER(type, instancetype) \
|
||||
bool HeapObject::Is##type() const { \
|
||||
return map()->instance_type() == instancetype; \
|
||||
}
|
||||
|
||||
TYPE_CHECKER(BreakPointInfo, TUPLE2_TYPE)
|
||||
TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
|
||||
TYPE_CHECKER(BytecodeArray, BYTECODE_ARRAY_TYPE)
|
||||
@ -602,9 +529,15 @@ bool Object::IsMinusZero() const {
|
||||
// Cast operations
|
||||
|
||||
CAST_ACCESSOR(AbstractCode)
|
||||
CAST_ACCESSOR(AccessCheckInfo)
|
||||
CAST_ACCESSOR(AccessorInfo)
|
||||
CAST_ACCESSOR(AccessorPair)
|
||||
CAST_ACCESSOR(AliasedArgumentsEntry)
|
||||
CAST_ACCESSOR(AllocationMemento)
|
||||
CAST_ACCESSOR(AllocationSite)
|
||||
CAST_ACCESSOR(ArrayList)
|
||||
CAST_ACCESSOR(AsyncGeneratorRequest)
|
||||
CAST_ACCESSOR(BoilerplateDescription)
|
||||
CAST_ACCESSOR(BreakPointInfo)
|
||||
CAST_ACCESSOR(ByteArray)
|
||||
CAST_ACCESSOR(BytecodeArray)
|
||||
CAST_ACCESSOR(CallHandlerInfo)
|
||||
@ -612,6 +545,7 @@ CAST_ACCESSOR(Cell)
|
||||
CAST_ACCESSOR(Code)
|
||||
CAST_ACCESSOR(ConsString)
|
||||
CAST_ACCESSOR(ConstantElementsPair)
|
||||
CAST_ACCESSOR(ContextExtension)
|
||||
CAST_ACCESSOR(DeoptimizationInputData)
|
||||
CAST_ACCESSOR(DeoptimizationOutputData)
|
||||
CAST_ACCESSOR(DependentCode)
|
||||
@ -624,19 +558,23 @@ CAST_ACCESSOR(FixedArrayBase)
|
||||
CAST_ACCESSOR(FixedDoubleArray)
|
||||
CAST_ACCESSOR(FixedTypedArrayBase)
|
||||
CAST_ACCESSOR(Foreign)
|
||||
CAST_ACCESSOR(FunctionTemplateInfo)
|
||||
CAST_ACCESSOR(GlobalDictionary)
|
||||
CAST_ACCESSOR(HandlerTable)
|
||||
CAST_ACCESSOR(HeapObject)
|
||||
CAST_ACCESSOR(InterceptorInfo)
|
||||
CAST_ACCESSOR(JSArgumentsObject);
|
||||
CAST_ACCESSOR(JSArray)
|
||||
CAST_ACCESSOR(JSArrayBuffer)
|
||||
CAST_ACCESSOR(JSArrayBufferView)
|
||||
CAST_ACCESSOR(JSArrayIterator)
|
||||
CAST_ACCESSOR(JSAsyncFromSyncIterator)
|
||||
CAST_ACCESSOR(JSAsyncGeneratorObject)
|
||||
CAST_ACCESSOR(JSBoundFunction)
|
||||
CAST_ACCESSOR(JSDataView)
|
||||
CAST_ACCESSOR(JSDate)
|
||||
CAST_ACCESSOR(JSFunction)
|
||||
CAST_ACCESSOR(JSGeneratorObject)
|
||||
CAST_ACCESSOR(JSAsyncGeneratorObject)
|
||||
CAST_ACCESSOR(JSGlobalObject)
|
||||
CAST_ACCESSOR(JSGlobalProxy)
|
||||
CAST_ACCESSOR(JSMap)
|
||||
@ -644,65 +582,67 @@ CAST_ACCESSOR(JSMapIterator)
|
||||
CAST_ACCESSOR(JSMessageObject)
|
||||
CAST_ACCESSOR(JSModuleNamespace)
|
||||
CAST_ACCESSOR(JSObject)
|
||||
CAST_ACCESSOR(JSPromise)
|
||||
CAST_ACCESSOR(JSPromiseCapability)
|
||||
CAST_ACCESSOR(JSProxy)
|
||||
CAST_ACCESSOR(JSReceiver)
|
||||
CAST_ACCESSOR(JSRegExp)
|
||||
CAST_ACCESSOR(JSPromiseCapability)
|
||||
CAST_ACCESSOR(JSPromise)
|
||||
CAST_ACCESSOR(JSSet)
|
||||
CAST_ACCESSOR(JSSetIterator)
|
||||
CAST_ACCESSOR(JSSloppyArgumentsObject)
|
||||
CAST_ACCESSOR(JSAsyncFromSyncIterator)
|
||||
CAST_ACCESSOR(JSStringIterator)
|
||||
CAST_ACCESSOR(JSArrayIterator)
|
||||
CAST_ACCESSOR(JSTypedArray)
|
||||
CAST_ACCESSOR(JSValue)
|
||||
CAST_ACCESSOR(JSWeakCollection)
|
||||
CAST_ACCESSOR(JSWeakMap)
|
||||
CAST_ACCESSOR(JSWeakSet)
|
||||
CAST_ACCESSOR(LayoutDescriptor)
|
||||
CAST_ACCESSOR(Module)
|
||||
CAST_ACCESSOR(ModuleInfo)
|
||||
CAST_ACCESSOR(ModuleInfoEntry)
|
||||
CAST_ACCESSOR(Name)
|
||||
CAST_ACCESSOR(NameDictionary)
|
||||
CAST_ACCESSOR(NormalizedMapCache)
|
||||
CAST_ACCESSOR(Object)
|
||||
CAST_ACCESSOR(ObjectHashTable)
|
||||
CAST_ACCESSOR(ObjectHashSet)
|
||||
CAST_ACCESSOR(ObjectHashTable)
|
||||
CAST_ACCESSOR(ObjectTemplateInfo)
|
||||
CAST_ACCESSOR(Oddball)
|
||||
CAST_ACCESSOR(OrderedHashMap)
|
||||
CAST_ACCESSOR(OrderedHashSet)
|
||||
CAST_ACCESSOR(PromiseReactionJobInfo)
|
||||
CAST_ACCESSOR(PromiseResolveThenableJobInfo)
|
||||
CAST_ACCESSOR(PropertyCell)
|
||||
CAST_ACCESSOR(TemplateList)
|
||||
CAST_ACCESSOR(PrototypeInfo)
|
||||
CAST_ACCESSOR(RegExpMatchInfo)
|
||||
CAST_ACCESSOR(ScopeInfo)
|
||||
CAST_ACCESSOR(Script)
|
||||
CAST_ACCESSOR(SeededNumberDictionary)
|
||||
CAST_ACCESSOR(SeqOneByteString)
|
||||
CAST_ACCESSOR(SeqString)
|
||||
CAST_ACCESSOR(SeqTwoByteString)
|
||||
CAST_ACCESSOR(SharedFunctionInfo)
|
||||
CAST_ACCESSOR(SourcePositionTableWithFrameCache)
|
||||
CAST_ACCESSOR(SlicedString)
|
||||
CAST_ACCESSOR(SloppyArgumentsElements)
|
||||
CAST_ACCESSOR(Smi)
|
||||
CAST_ACCESSOR(SourcePositionTableWithFrameCache)
|
||||
CAST_ACCESSOR(StackFrameInfo)
|
||||
CAST_ACCESSOR(String)
|
||||
CAST_ACCESSOR(StringSet)
|
||||
CAST_ACCESSOR(StringTable)
|
||||
CAST_ACCESSOR(Struct)
|
||||
CAST_ACCESSOR(Symbol)
|
||||
CAST_ACCESSOR(TemplateInfo)
|
||||
CAST_ACCESSOR(TemplateList)
|
||||
CAST_ACCESSOR(ThinString)
|
||||
CAST_ACCESSOR(Tuple2)
|
||||
CAST_ACCESSOR(Tuple3)
|
||||
CAST_ACCESSOR(TypeFeedbackInfo)
|
||||
CAST_ACCESSOR(UnseededNumberDictionary)
|
||||
CAST_ACCESSOR(WeakCell)
|
||||
CAST_ACCESSOR(WeakFixedArray)
|
||||
CAST_ACCESSOR(WeakHashTable)
|
||||
|
||||
#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
|
||||
STRUCT_LIST(MAKE_STRUCT_CAST)
|
||||
#undef MAKE_STRUCT_CAST
|
||||
|
||||
#undef CAST_ACCESSOR
|
||||
|
||||
bool Object::HasValidElements() {
|
||||
// Dictionary is covered under FixedArray.
|
||||
return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
|
||||
@ -1267,150 +1207,6 @@ bool JSObject::PrototypeHasNoElements(Isolate* isolate, JSObject* object) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#define FIELD_ADDR(p, offset) \
|
||||
(reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
|
||||
|
||||
#define FIELD_ADDR_CONST(p, offset) \
|
||||
(reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
|
||||
|
||||
#define READ_FIELD(p, offset) \
|
||||
(*reinterpret_cast<Object* const*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define ACQUIRE_READ_FIELD(p, offset) \
|
||||
reinterpret_cast<Object*>(base::Acquire_Load( \
|
||||
reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
|
||||
|
||||
#define NOBARRIER_READ_FIELD(p, offset) \
|
||||
reinterpret_cast<Object*>(base::NoBarrier_Load( \
|
||||
reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
|
||||
|
||||
#ifdef V8_CONCURRENT_MARKING
|
||||
#define WRITE_FIELD(p, offset, value) \
|
||||
base::NoBarrier_Store( \
|
||||
reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
|
||||
reinterpret_cast<base::AtomicWord>(value));
|
||||
#else
|
||||
#define WRITE_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
|
||||
#endif
|
||||
|
||||
#define RELEASE_WRITE_FIELD(p, offset, value) \
|
||||
base::Release_Store( \
|
||||
reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
|
||||
reinterpret_cast<base::AtomicWord>(value));
|
||||
|
||||
#define NOBARRIER_WRITE_FIELD(p, offset, value) \
|
||||
base::NoBarrier_Store( \
|
||||
reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
|
||||
reinterpret_cast<base::AtomicWord>(value));
|
||||
|
||||
#define WRITE_BARRIER(heap, object, offset, value) \
|
||||
heap->incremental_marking()->RecordWrite( \
|
||||
object, HeapObject::RawField(object, offset), value); \
|
||||
heap->RecordWrite(object, offset, value);
|
||||
|
||||
#define FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(heap, array, start, length) \
|
||||
do { \
|
||||
heap->RecordFixedArrayElements(array, start, length); \
|
||||
heap->incremental_marking()->IterateBlackObject(array); \
|
||||
} while (false)
|
||||
|
||||
#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
|
||||
if (mode != SKIP_WRITE_BARRIER) { \
|
||||
if (mode == UPDATE_WRITE_BARRIER) { \
|
||||
heap->incremental_marking()->RecordWrite( \
|
||||
object, HeapObject::RawField(object, offset), value); \
|
||||
} \
|
||||
heap->RecordWrite(object, offset, value); \
|
||||
}
|
||||
|
||||
#define READ_DOUBLE_FIELD(p, offset) \
|
||||
ReadDoubleValue(FIELD_ADDR_CONST(p, offset))
|
||||
|
||||
#define WRITE_DOUBLE_FIELD(p, offset, value) \
|
||||
WriteDoubleValue(FIELD_ADDR(p, offset), value)
|
||||
|
||||
#define READ_INT_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INTPTR_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const intptr_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INTPTR_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT8_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint8_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT8_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint8_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT8_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int8_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT8_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int8_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT16_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint16_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT16_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT16_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int16_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT16_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int16_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT32_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint32_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT32_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT32_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT32_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_FLOAT_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const float*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_FLOAT_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<float*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT64_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint64_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT64_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint64_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT64_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT64_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_BYTE_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define NOBARRIER_READ_BYTE_FIELD(p, offset) \
|
||||
static_cast<byte>(base::NoBarrier_Load( \
|
||||
reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset))))
|
||||
|
||||
#define WRITE_BYTE_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value) \
|
||||
base::NoBarrier_Store( \
|
||||
reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
|
||||
static_cast<base::Atomic8>(value));
|
||||
|
||||
Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
|
||||
return reinterpret_cast<Object**>(FIELD_ADDR(obj, byte_offset));
|
||||
}
|
||||
@ -5841,41 +5637,6 @@ void Script::set_origin_options(ScriptOriginOptions origin_options) {
|
||||
(origin_options.Flags() << kOriginOptionsShift));
|
||||
}
|
||||
|
||||
|
||||
ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
|
||||
SMI_ACCESSORS(DebugInfo, debugger_hints, kDebuggerHintsIndex)
|
||||
ACCESSORS(DebugInfo, debug_bytecode_array, Object, kDebugBytecodeArrayIndex)
|
||||
ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
|
||||
|
||||
bool DebugInfo::HasDebugBytecodeArray() {
|
||||
return debug_bytecode_array()->IsBytecodeArray();
|
||||
}
|
||||
|
||||
bool DebugInfo::HasDebugCode() {
|
||||
Code* code = shared()->code();
|
||||
bool has = code->kind() == Code::FUNCTION;
|
||||
DCHECK(!has || code->has_debug_break_slots());
|
||||
return has;
|
||||
}
|
||||
|
||||
BytecodeArray* DebugInfo::OriginalBytecodeArray() {
|
||||
DCHECK(HasDebugBytecodeArray());
|
||||
return shared()->bytecode_array();
|
||||
}
|
||||
|
||||
BytecodeArray* DebugInfo::DebugBytecodeArray() {
|
||||
DCHECK(HasDebugBytecodeArray());
|
||||
return BytecodeArray::cast(debug_bytecode_array());
|
||||
}
|
||||
|
||||
Code* DebugInfo::DebugCode() {
|
||||
DCHECK(HasDebugCode());
|
||||
return shared()->code();
|
||||
}
|
||||
|
||||
SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
|
||||
ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
|
||||
|
||||
SMI_ACCESSORS(StackFrameInfo, line_number, kLineNumberIndex)
|
||||
SMI_ACCESSORS(StackFrameInfo, column_number, kColumnNumberIndex)
|
||||
SMI_ACCESSORS(StackFrameInfo, script_id, kScriptIdIndex)
|
||||
@ -6204,29 +5965,11 @@ bool SharedFunctionInfo::HasDebugInfo() const {
|
||||
return has_debug_info;
|
||||
}
|
||||
|
||||
DebugInfo* SharedFunctionInfo::GetDebugInfo() const {
|
||||
DCHECK(HasDebugInfo());
|
||||
return DebugInfo::cast(debug_info());
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasDebugCode() const {
|
||||
if (HasBaselineCode()) return code()->has_debug_break_slots();
|
||||
return HasBytecodeArray();
|
||||
}
|
||||
|
||||
int SharedFunctionInfo::debugger_hints() const {
|
||||
if (HasDebugInfo()) return GetDebugInfo()->debugger_hints();
|
||||
return Smi::cast(debug_info())->value();
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_debugger_hints(int value) {
|
||||
if (HasDebugInfo()) {
|
||||
GetDebugInfo()->set_debugger_hints(value);
|
||||
} else {
|
||||
set_debug_info(Smi::FromInt(value));
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::IsApiFunction() {
|
||||
return function_data()->IsFunctionTemplateInfo();
|
||||
}
|
||||
@ -8206,52 +7949,6 @@ ACCESSORS(JSAsyncFromSyncIterator, sync_iterator, JSReceiver,
|
||||
ACCESSORS(JSStringIterator, string, String, kStringOffset)
|
||||
SMI_ACCESSORS(JSStringIterator, index, kNextIndexOffset)
|
||||
|
||||
#undef INT_ACCESSORS
|
||||
#undef ACCESSORS
|
||||
#undef ACCESSORS_CHECKED
|
||||
#undef ACCESSORS_CHECKED2
|
||||
#undef SMI_ACCESSORS
|
||||
#undef SYNCHRONIZED_SMI_ACCESSORS
|
||||
#undef NOBARRIER_SMI_ACCESSORS
|
||||
#undef BOOL_GETTER
|
||||
#undef BOOL_ACCESSORS
|
||||
#undef FIELD_ADDR
|
||||
#undef FIELD_ADDR_CONST
|
||||
#undef READ_FIELD
|
||||
#undef NOBARRIER_READ_FIELD
|
||||
#undef WRITE_FIELD
|
||||
#undef NOBARRIER_WRITE_FIELD
|
||||
#undef WRITE_BARRIER
|
||||
#undef CONDITIONAL_WRITE_BARRIER
|
||||
#undef READ_DOUBLE_FIELD
|
||||
#undef WRITE_DOUBLE_FIELD
|
||||
#undef READ_INT_FIELD
|
||||
#undef WRITE_INT_FIELD
|
||||
#undef READ_INTPTR_FIELD
|
||||
#undef WRITE_INTPTR_FIELD
|
||||
#undef READ_UINT8_FIELD
|
||||
#undef WRITE_UINT8_FIELD
|
||||
#undef READ_INT8_FIELD
|
||||
#undef WRITE_INT8_FIELD
|
||||
#undef READ_UINT16_FIELD
|
||||
#undef WRITE_UINT16_FIELD
|
||||
#undef READ_INT16_FIELD
|
||||
#undef WRITE_INT16_FIELD
|
||||
#undef READ_UINT32_FIELD
|
||||
#undef WRITE_UINT32_FIELD
|
||||
#undef READ_INT32_FIELD
|
||||
#undef WRITE_INT32_FIELD
|
||||
#undef READ_FLOAT_FIELD
|
||||
#undef WRITE_FLOAT_FIELD
|
||||
#undef READ_UINT64_FIELD
|
||||
#undef WRITE_UINT64_FIELD
|
||||
#undef READ_INT64_FIELD
|
||||
#undef WRITE_INT64_FIELD
|
||||
#undef READ_BYTE_FIELD
|
||||
#undef WRITE_BYTE_FIELD
|
||||
#undef NOBARRIER_READ_BYTE_FIELD
|
||||
#undef NOBARRIER_WRITE_BYTE_FIELD
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/disassembler.h"
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/ostreams.h"
|
||||
#include "src/regexp/jsregexp.h"
|
||||
|
||||
|
262
src/objects.cc
262
src/objects.cc
@ -57,6 +57,7 @@
|
||||
#include "src/objects-body-descriptors-inl.h"
|
||||
#include "src/objects/code-cache-inl.h"
|
||||
#include "src/objects/compilation-cache-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/frame-array-inl.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/property-descriptor.h"
|
||||
@ -13417,6 +13418,23 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
|
||||
shared->set_script(*script_object);
|
||||
}
|
||||
|
||||
DebugInfo* SharedFunctionInfo::GetDebugInfo() const {
|
||||
DCHECK(HasDebugInfo());
|
||||
return DebugInfo::cast(debug_info());
|
||||
}
|
||||
|
||||
int SharedFunctionInfo::debugger_hints() const {
|
||||
if (HasDebugInfo()) return GetDebugInfo()->debugger_hints();
|
||||
return Smi::cast(debug_info())->value();
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_debugger_hints(int value) {
|
||||
if (HasDebugInfo()) {
|
||||
GetDebugInfo()->set_debugger_hints(value);
|
||||
} else {
|
||||
set_debug_info(Smi::FromInt(value));
|
||||
}
|
||||
}
|
||||
|
||||
String* SharedFunctionInfo::DebugName() {
|
||||
Object* n = name();
|
||||
@ -19107,250 +19125,6 @@ Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
|
||||
return isolate->factory()->NewJSArrayWithElements(entries);
|
||||
}
|
||||
|
||||
// Check if there is a break point at this source position.
|
||||
bool DebugInfo::HasBreakPoint(int source_position) {
|
||||
// Get the break point info object for this code offset.
|
||||
Object* break_point_info = GetBreakPointInfo(source_position);
|
||||
|
||||
// If there is no break point info object or no break points in the break
|
||||
// point info object there is no break point at this code offset.
|
||||
if (break_point_info->IsUndefined(GetIsolate())) return false;
|
||||
return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
|
||||
}
|
||||
|
||||
// Get the break point info object for this source position.
|
||||
Object* DebugInfo::GetBreakPointInfo(int source_position) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (!break_points()->IsUndefined(isolate)) {
|
||||
for (int i = 0; i < break_points()->length(); i++) {
|
||||
if (!break_points()->get(i)->IsUndefined(isolate)) {
|
||||
BreakPointInfo* break_point_info =
|
||||
BreakPointInfo::cast(break_points()->get(i));
|
||||
if (break_point_info->source_position() == source_position) {
|
||||
return break_point_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
if (debug_info->break_points()->IsUndefined(isolate)) return false;
|
||||
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue;
|
||||
Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
|
||||
BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
|
||||
if (BreakPointInfo::HasBreakPointObject(break_point_info,
|
||||
break_point_object)) {
|
||||
BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
Handle<Object> break_point_info(
|
||||
debug_info->GetBreakPointInfo(source_position), isolate);
|
||||
if (!break_point_info->IsUndefined(isolate)) {
|
||||
BreakPointInfo::SetBreakPoint(
|
||||
Handle<BreakPointInfo>::cast(break_point_info),
|
||||
break_point_object);
|
||||
return;
|
||||
}
|
||||
|
||||
// Adding a new break point for a code offset which did not have any
|
||||
// break points before. Try to find a free slot.
|
||||
static const int kNoBreakPointInfo = -1;
|
||||
int index = kNoBreakPointInfo;
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (debug_info->break_points()->get(i)->IsUndefined(isolate)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == kNoBreakPointInfo) {
|
||||
// No free slot - extend break point info array.
|
||||
Handle<FixedArray> old_break_points = Handle<FixedArray>(
|
||||
FixedArray::cast(debug_info->break_points()), isolate);
|
||||
Handle<FixedArray> new_break_points =
|
||||
isolate->factory()->NewFixedArray(
|
||||
old_break_points->length() +
|
||||
DebugInfo::kEstimatedNofBreakPointsInFunction);
|
||||
|
||||
debug_info->set_break_points(*new_break_points);
|
||||
for (int i = 0; i < old_break_points->length(); i++) {
|
||||
new_break_points->set(i, old_break_points->get(i));
|
||||
}
|
||||
index = old_break_points->length();
|
||||
}
|
||||
DCHECK(index != kNoBreakPointInfo);
|
||||
|
||||
// Allocate new BreakPointInfo object and set the break point.
|
||||
Handle<BreakPointInfo> new_break_point_info =
|
||||
isolate->factory()->NewBreakPointInfo(source_position);
|
||||
BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
|
||||
debug_info->break_points()->set(index, *new_break_point_info);
|
||||
}
|
||||
|
||||
// Get the break point objects for a source position.
|
||||
Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) {
|
||||
Object* break_point_info = GetBreakPointInfo(source_position);
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (break_point_info->IsUndefined(isolate)) {
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
return Handle<Object>(
|
||||
BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate);
|
||||
}
|
||||
|
||||
|
||||
// Get the total number of break points.
|
||||
int DebugInfo::GetBreakPointCount() {
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (break_points()->IsUndefined(isolate)) return 0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < break_points()->length(); i++) {
|
||||
if (!break_points()->get(i)->IsUndefined(isolate)) {
|
||||
BreakPointInfo* break_point_info =
|
||||
BreakPointInfo::cast(break_points()->get(i));
|
||||
count += break_point_info->GetBreakPointCount();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> DebugInfo::FindBreakPointInfo(
|
||||
Handle<DebugInfo> debug_info, Handle<Object> break_point_object) {
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
if (!debug_info->break_points()->IsUndefined(isolate)) {
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
|
||||
Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
|
||||
BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
|
||||
if (BreakPointInfo::HasBreakPointObject(break_point_info,
|
||||
break_point_object)) {
|
||||
return break_point_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
// Remove the specified break point object.
|
||||
void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
// If there are no break points just ignore.
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) return;
|
||||
// If there is a single break point clear it if it is the same.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
if (break_point_info->break_point_objects() == *break_point_object) {
|
||||
break_point_info->set_break_point_objects(
|
||||
isolate->heap()->undefined_value());
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If there are multiple break points shrink the array
|
||||
DCHECK(break_point_info->break_point_objects()->IsFixedArray());
|
||||
Handle<FixedArray> old_array =
|
||||
Handle<FixedArray>(
|
||||
FixedArray::cast(break_point_info->break_point_objects()));
|
||||
Handle<FixedArray> new_array =
|
||||
isolate->factory()->NewFixedArray(old_array->length() - 1);
|
||||
int found_count = 0;
|
||||
for (int i = 0; i < old_array->length(); i++) {
|
||||
if (old_array->get(i) == *break_point_object) {
|
||||
DCHECK(found_count == 0);
|
||||
found_count++;
|
||||
} else {
|
||||
new_array->set(i - found_count, old_array->get(i));
|
||||
}
|
||||
}
|
||||
// If the break point was found in the list change it.
|
||||
if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
|
||||
}
|
||||
|
||||
|
||||
// Add the specified break point object.
|
||||
void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
|
||||
// If there was no break point objects before just set it.
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
|
||||
break_point_info->set_break_point_objects(*break_point_object);
|
||||
return;
|
||||
}
|
||||
// If the break point object is the same as before just ignore.
|
||||
if (break_point_info->break_point_objects() == *break_point_object) return;
|
||||
// If there was one break point object before replace with array.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
|
||||
array->set(0, break_point_info->break_point_objects());
|
||||
array->set(1, *break_point_object);
|
||||
break_point_info->set_break_point_objects(*array);
|
||||
return;
|
||||
}
|
||||
// If there was more than one break point before extend array.
|
||||
Handle<FixedArray> old_array =
|
||||
Handle<FixedArray>(
|
||||
FixedArray::cast(break_point_info->break_point_objects()));
|
||||
Handle<FixedArray> new_array =
|
||||
isolate->factory()->NewFixedArray(old_array->length() + 1);
|
||||
for (int i = 0; i < old_array->length(); i++) {
|
||||
// If the break point was there before just ignore.
|
||||
if (old_array->get(i) == *break_point_object) return;
|
||||
new_array->set(i, old_array->get(i));
|
||||
}
|
||||
// Add the new break point.
|
||||
new_array->set(old_array->length(), *break_point_object);
|
||||
break_point_info->set_break_point_objects(*new_array);
|
||||
}
|
||||
|
||||
|
||||
bool BreakPointInfo::HasBreakPointObject(
|
||||
Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
// No break point.
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
|
||||
return false;
|
||||
}
|
||||
// Single break point.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
return break_point_info->break_point_objects() == *break_point_object;
|
||||
}
|
||||
// Multiple break points.
|
||||
FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
|
||||
for (int i = 0; i < array->length(); i++) {
|
||||
if (array->get(i) == *break_point_object) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Get the number of break points.
|
||||
int BreakPointInfo::GetBreakPointCount() {
|
||||
// No break point.
|
||||
if (break_point_objects()->IsUndefined(GetIsolate())) return 0;
|
||||
// Single break point.
|
||||
if (!break_point_objects()->IsFixedArray()) return 1;
|
||||
// Multiple break points.
|
||||
return FixedArray::cast(break_point_objects())->length();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
|
||||
Handle<JSReceiver> new_target, double tv) {
|
||||
|
102
src/objects.h
102
src/objects.h
@ -5181,7 +5181,7 @@ class SharedFunctionInfo: public HeapObject {
|
||||
|
||||
// The function is subject to debugging if a debug info is attached.
|
||||
inline bool HasDebugInfo() const;
|
||||
inline DebugInfo* GetDebugInfo() const;
|
||||
DebugInfo* GetDebugInfo() const;
|
||||
|
||||
// A function has debug code if the compiled code has debug break slots.
|
||||
inline bool HasDebugCode() const;
|
||||
@ -5192,8 +5192,8 @@ class SharedFunctionInfo: public HeapObject {
|
||||
// Bit field containing various information collected for debugging.
|
||||
// This field is either stored on the kDebugInfo slot or inside the
|
||||
// debug info struct.
|
||||
inline int debugger_hints() const;
|
||||
inline void set_debugger_hints(int value);
|
||||
int debugger_hints() const;
|
||||
void set_debugger_hints(int value);
|
||||
|
||||
// Indicates that the function was created by the Function function.
|
||||
// Though it's anonymous, toString should treat it as if it had the name
|
||||
@ -9204,102 +9204,6 @@ class ObjectTemplateInfo: public TemplateInfo {
|
||||
: public BitField<int, IsImmutablePrototype::kNext, 29> {};
|
||||
};
|
||||
|
||||
|
||||
// The DebugInfo class holds additional information for a function being
|
||||
// debugged.
|
||||
class DebugInfo: public Struct {
|
||||
public:
|
||||
// The shared function info for the source being debugged.
|
||||
DECL_ACCESSORS(shared, SharedFunctionInfo)
|
||||
|
||||
// Bit field containing various information collected for debugging.
|
||||
DECL_INT_ACCESSORS(debugger_hints)
|
||||
|
||||
DECL_ACCESSORS(debug_bytecode_array, Object)
|
||||
// Fixed array holding status information for each active break point.
|
||||
DECL_ACCESSORS(break_points, FixedArray)
|
||||
|
||||
// Check if there is a break point at a source position.
|
||||
bool HasBreakPoint(int source_position);
|
||||
// Attempt to clear a break point. Return true if successful.
|
||||
static bool ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object);
|
||||
// Set a break point.
|
||||
static void SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
Handle<Object> break_point_object);
|
||||
// Get the break point objects for a source position.
|
||||
Handle<Object> GetBreakPointObjects(int source_position);
|
||||
// Find the break point info holding this break point object.
|
||||
static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object);
|
||||
// Get the number of break points for this function.
|
||||
int GetBreakPointCount();
|
||||
|
||||
inline bool HasDebugBytecodeArray();
|
||||
inline bool HasDebugCode();
|
||||
|
||||
inline BytecodeArray* OriginalBytecodeArray();
|
||||
inline BytecodeArray* DebugBytecodeArray();
|
||||
inline Code* DebugCode();
|
||||
|
||||
DECLARE_CAST(DebugInfo)
|
||||
|
||||
// Dispatched behavior.
|
||||
DECLARE_PRINTER(DebugInfo)
|
||||
DECLARE_VERIFIER(DebugInfo)
|
||||
|
||||
static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
|
||||
static const int kDebuggerHintsIndex =
|
||||
kSharedFunctionInfoIndex + kPointerSize;
|
||||
static const int kDebugBytecodeArrayIndex =
|
||||
kDebuggerHintsIndex + kPointerSize;
|
||||
static const int kBreakPointsStateIndex =
|
||||
kDebugBytecodeArrayIndex + kPointerSize;
|
||||
static const int kSize = kBreakPointsStateIndex + kPointerSize;
|
||||
|
||||
static const int kEstimatedNofBreakPointsInFunction = 4;
|
||||
|
||||
private:
|
||||
// Get the break point info object for a source position.
|
||||
Object* GetBreakPointInfo(int source_position);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
|
||||
};
|
||||
|
||||
|
||||
// The BreakPointInfo class holds information for break points set in a
|
||||
// function. The DebugInfo object holds a BreakPointInfo object for each code
|
||||
// position with one or more break points.
|
||||
class BreakPointInfo : public Tuple2 {
|
||||
public:
|
||||
// The position in the source for the break position.
|
||||
DECL_INT_ACCESSORS(source_position)
|
||||
// List of related JavaScript break points.
|
||||
DECL_ACCESSORS(break_point_objects, Object)
|
||||
|
||||
// Removes a break point.
|
||||
static void ClearBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Set a break point.
|
||||
static void SetBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Check if break point info has this break point object.
|
||||
static bool HasBreakPointObject(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Get the number of break points for this code offset.
|
||||
int GetBreakPointCount();
|
||||
|
||||
int GetStatementPosition(Handle<DebugInfo> debug_info);
|
||||
|
||||
DECLARE_CAST(BreakPointInfo)
|
||||
|
||||
static const int kSourcePositionIndex = kValue1Offset;
|
||||
static const int kBreakPointObjectsIndex = kValue2Offset;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
|
||||
};
|
||||
|
||||
class StackFrameInfo : public Struct {
|
||||
public:
|
||||
DECL_INT_ACCESSORS(line_number)
|
||||
|
60
src/objects/debug-objects-inl.h
Normal file
60
src/objects/debug-objects-inl.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_OBJECTS_DEBUG_OBJECTS_INL_H_
|
||||
#define V8_OBJECTS_DEBUG_OBJECTS_INL_H_
|
||||
|
||||
#include "src/objects/debug-objects.h"
|
||||
|
||||
#include "src/heap/heap-inl.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
CAST_ACCESSOR(BreakPointInfo)
|
||||
CAST_ACCESSOR(DebugInfo)
|
||||
|
||||
ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
|
||||
SMI_ACCESSORS(DebugInfo, debugger_hints, kDebuggerHintsIndex)
|
||||
ACCESSORS(DebugInfo, debug_bytecode_array, Object, kDebugBytecodeArrayIndex)
|
||||
ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
|
||||
|
||||
SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
|
||||
ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
|
||||
|
||||
bool DebugInfo::HasDebugBytecodeArray() {
|
||||
return debug_bytecode_array()->IsBytecodeArray();
|
||||
}
|
||||
|
||||
bool DebugInfo::HasDebugCode() {
|
||||
Code* code = shared()->code();
|
||||
bool has = code->kind() == Code::FUNCTION;
|
||||
DCHECK(!has || code->has_debug_break_slots());
|
||||
return has;
|
||||
}
|
||||
|
||||
BytecodeArray* DebugInfo::OriginalBytecodeArray() {
|
||||
DCHECK(HasDebugBytecodeArray());
|
||||
return shared()->bytecode_array();
|
||||
}
|
||||
|
||||
BytecodeArray* DebugInfo::DebugBytecodeArray() {
|
||||
DCHECK(HasDebugBytecodeArray());
|
||||
return BytecodeArray::cast(debug_bytecode_array());
|
||||
}
|
||||
|
||||
Code* DebugInfo::DebugCode() {
|
||||
DCHECK(HasDebugCode());
|
||||
return shared()->code();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_OBJECTS_DEBUG_OBJECTS_INL_H_
|
246
src/objects/debug-objects.cc
Normal file
246
src/objects/debug-objects.cc
Normal file
@ -0,0 +1,246 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/objects/debug-objects.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// Check if there is a break point at this source position.
|
||||
bool DebugInfo::HasBreakPoint(int source_position) {
|
||||
// Get the break point info object for this code offset.
|
||||
Object* break_point_info = GetBreakPointInfo(source_position);
|
||||
|
||||
// If there is no break point info object or no break points in the break
|
||||
// point info object there is no break point at this code offset.
|
||||
if (break_point_info->IsUndefined(GetIsolate())) return false;
|
||||
return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
|
||||
}
|
||||
|
||||
// Get the break point info object for this source position.
|
||||
Object* DebugInfo::GetBreakPointInfo(int source_position) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (!break_points()->IsUndefined(isolate)) {
|
||||
for (int i = 0; i < break_points()->length(); i++) {
|
||||
if (!break_points()->get(i)->IsUndefined(isolate)) {
|
||||
BreakPointInfo* break_point_info =
|
||||
BreakPointInfo::cast(break_points()->get(i));
|
||||
if (break_point_info->source_position() == source_position) {
|
||||
return break_point_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
if (debug_info->break_points()->IsUndefined(isolate)) return false;
|
||||
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue;
|
||||
Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
|
||||
BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
|
||||
if (BreakPointInfo::HasBreakPointObject(break_point_info,
|
||||
break_point_object)) {
|
||||
BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
Handle<Object> break_point_info(
|
||||
debug_info->GetBreakPointInfo(source_position), isolate);
|
||||
if (!break_point_info->IsUndefined(isolate)) {
|
||||
BreakPointInfo::SetBreakPoint(
|
||||
Handle<BreakPointInfo>::cast(break_point_info), break_point_object);
|
||||
return;
|
||||
}
|
||||
|
||||
// Adding a new break point for a code offset which did not have any
|
||||
// break points before. Try to find a free slot.
|
||||
static const int kNoBreakPointInfo = -1;
|
||||
int index = kNoBreakPointInfo;
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (debug_info->break_points()->get(i)->IsUndefined(isolate)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == kNoBreakPointInfo) {
|
||||
// No free slot - extend break point info array.
|
||||
Handle<FixedArray> old_break_points = Handle<FixedArray>(
|
||||
FixedArray::cast(debug_info->break_points()), isolate);
|
||||
Handle<FixedArray> new_break_points = isolate->factory()->NewFixedArray(
|
||||
old_break_points->length() +
|
||||
DebugInfo::kEstimatedNofBreakPointsInFunction);
|
||||
|
||||
debug_info->set_break_points(*new_break_points);
|
||||
for (int i = 0; i < old_break_points->length(); i++) {
|
||||
new_break_points->set(i, old_break_points->get(i));
|
||||
}
|
||||
index = old_break_points->length();
|
||||
}
|
||||
DCHECK(index != kNoBreakPointInfo);
|
||||
|
||||
// Allocate new BreakPointInfo object and set the break point.
|
||||
Handle<BreakPointInfo> new_break_point_info =
|
||||
isolate->factory()->NewBreakPointInfo(source_position);
|
||||
BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
|
||||
debug_info->break_points()->set(index, *new_break_point_info);
|
||||
}
|
||||
|
||||
// Get the break point objects for a source position.
|
||||
Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) {
|
||||
Object* break_point_info = GetBreakPointInfo(source_position);
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (break_point_info->IsUndefined(isolate)) {
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
return Handle<Object>(
|
||||
BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate);
|
||||
}
|
||||
|
||||
// Get the total number of break points.
|
||||
int DebugInfo::GetBreakPointCount() {
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (break_points()->IsUndefined(isolate)) return 0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < break_points()->length(); i++) {
|
||||
if (!break_points()->get(i)->IsUndefined(isolate)) {
|
||||
BreakPointInfo* break_point_info =
|
||||
BreakPointInfo::cast(break_points()->get(i));
|
||||
count += break_point_info->GetBreakPointCount();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Handle<Object> DebugInfo::FindBreakPointInfo(
|
||||
Handle<DebugInfo> debug_info, Handle<Object> break_point_object) {
|
||||
Isolate* isolate = debug_info->GetIsolate();
|
||||
if (!debug_info->break_points()->IsUndefined(isolate)) {
|
||||
for (int i = 0; i < debug_info->break_points()->length(); i++) {
|
||||
if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
|
||||
Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
|
||||
BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate);
|
||||
if (BreakPointInfo::HasBreakPointObject(break_point_info,
|
||||
break_point_object)) {
|
||||
return break_point_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
// Remove the specified break point object.
|
||||
void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
// If there are no break points just ignore.
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) return;
|
||||
// If there is a single break point clear it if it is the same.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
if (break_point_info->break_point_objects() == *break_point_object) {
|
||||
break_point_info->set_break_point_objects(
|
||||
isolate->heap()->undefined_value());
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If there are multiple break points shrink the array
|
||||
DCHECK(break_point_info->break_point_objects()->IsFixedArray());
|
||||
Handle<FixedArray> old_array = Handle<FixedArray>(
|
||||
FixedArray::cast(break_point_info->break_point_objects()));
|
||||
Handle<FixedArray> new_array =
|
||||
isolate->factory()->NewFixedArray(old_array->length() - 1);
|
||||
int found_count = 0;
|
||||
for (int i = 0; i < old_array->length(); i++) {
|
||||
if (old_array->get(i) == *break_point_object) {
|
||||
DCHECK(found_count == 0);
|
||||
found_count++;
|
||||
} else {
|
||||
new_array->set(i - found_count, old_array->get(i));
|
||||
}
|
||||
}
|
||||
// If the break point was found in the list change it.
|
||||
if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
|
||||
}
|
||||
|
||||
// Add the specified break point object.
|
||||
void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
|
||||
// If there was no break point objects before just set it.
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
|
||||
break_point_info->set_break_point_objects(*break_point_object);
|
||||
return;
|
||||
}
|
||||
// If the break point object is the same as before just ignore.
|
||||
if (break_point_info->break_point_objects() == *break_point_object) return;
|
||||
// If there was one break point object before replace with array.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
|
||||
array->set(0, break_point_info->break_point_objects());
|
||||
array->set(1, *break_point_object);
|
||||
break_point_info->set_break_point_objects(*array);
|
||||
return;
|
||||
}
|
||||
// If there was more than one break point before extend array.
|
||||
Handle<FixedArray> old_array = Handle<FixedArray>(
|
||||
FixedArray::cast(break_point_info->break_point_objects()));
|
||||
Handle<FixedArray> new_array =
|
||||
isolate->factory()->NewFixedArray(old_array->length() + 1);
|
||||
for (int i = 0; i < old_array->length(); i++) {
|
||||
// If the break point was there before just ignore.
|
||||
if (old_array->get(i) == *break_point_object) return;
|
||||
new_array->set(i, old_array->get(i));
|
||||
}
|
||||
// Add the new break point.
|
||||
new_array->set(old_array->length(), *break_point_object);
|
||||
break_point_info->set_break_point_objects(*new_array);
|
||||
}
|
||||
|
||||
bool BreakPointInfo::HasBreakPointObject(
|
||||
Handle<BreakPointInfo> break_point_info,
|
||||
Handle<Object> break_point_object) {
|
||||
// No break point.
|
||||
Isolate* isolate = break_point_info->GetIsolate();
|
||||
if (break_point_info->break_point_objects()->IsUndefined(isolate)) {
|
||||
return false;
|
||||
}
|
||||
// Single break point.
|
||||
if (!break_point_info->break_point_objects()->IsFixedArray()) {
|
||||
return break_point_info->break_point_objects() == *break_point_object;
|
||||
}
|
||||
// Multiple break points.
|
||||
FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
|
||||
for (int i = 0; i < array->length(); i++) {
|
||||
if (array->get(i) == *break_point_object) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the number of break points.
|
||||
int BreakPointInfo::GetBreakPointCount() {
|
||||
// No break point.
|
||||
if (break_point_objects()->IsUndefined(GetIsolate())) return 0;
|
||||
// Single break point.
|
||||
if (!break_point_objects()->IsFixedArray()) return 1;
|
||||
// Multiple break points.
|
||||
return FixedArray::cast(break_point_objects())->length();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
115
src/objects/debug-objects.h
Normal file
115
src/objects/debug-objects.h
Normal file
@ -0,0 +1,115 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_OBJECTS_DEBUG_OBJECTS_H_
|
||||
#define V8_OBJECTS_DEBUG_OBJECTS_H_
|
||||
|
||||
#include "src/objects.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// The DebugInfo class holds additional information for a function being
|
||||
// debugged.
|
||||
class DebugInfo : public Struct {
|
||||
public:
|
||||
// The shared function info for the source being debugged.
|
||||
DECL_ACCESSORS(shared, SharedFunctionInfo)
|
||||
|
||||
// Bit field containing various information collected for debugging.
|
||||
DECL_INT_ACCESSORS(debugger_hints)
|
||||
|
||||
DECL_ACCESSORS(debug_bytecode_array, Object)
|
||||
// Fixed array holding status information for each active break point.
|
||||
DECL_ACCESSORS(break_points, FixedArray)
|
||||
|
||||
// Check if there is a break point at a source position.
|
||||
bool HasBreakPoint(int source_position);
|
||||
// Attempt to clear a break point. Return true if successful.
|
||||
static bool ClearBreakPoint(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object);
|
||||
// Set a break point.
|
||||
static void SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
|
||||
Handle<Object> break_point_object);
|
||||
// Get the break point objects for a source position.
|
||||
Handle<Object> GetBreakPointObjects(int source_position);
|
||||
// Find the break point info holding this break point object.
|
||||
static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
|
||||
Handle<Object> break_point_object);
|
||||
// Get the number of break points for this function.
|
||||
int GetBreakPointCount();
|
||||
|
||||
inline bool HasDebugBytecodeArray();
|
||||
inline bool HasDebugCode();
|
||||
|
||||
inline BytecodeArray* OriginalBytecodeArray();
|
||||
inline BytecodeArray* DebugBytecodeArray();
|
||||
inline Code* DebugCode();
|
||||
|
||||
DECLARE_CAST(DebugInfo)
|
||||
|
||||
// Dispatched behavior.
|
||||
DECLARE_PRINTER(DebugInfo)
|
||||
DECLARE_VERIFIER(DebugInfo)
|
||||
|
||||
static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
|
||||
static const int kDebuggerHintsIndex =
|
||||
kSharedFunctionInfoIndex + kPointerSize;
|
||||
static const int kDebugBytecodeArrayIndex =
|
||||
kDebuggerHintsIndex + kPointerSize;
|
||||
static const int kBreakPointsStateIndex =
|
||||
kDebugBytecodeArrayIndex + kPointerSize;
|
||||
static const int kSize = kBreakPointsStateIndex + kPointerSize;
|
||||
|
||||
static const int kEstimatedNofBreakPointsInFunction = 4;
|
||||
|
||||
private:
|
||||
// Get the break point info object for a source position.
|
||||
Object* GetBreakPointInfo(int source_position);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
|
||||
};
|
||||
|
||||
// The BreakPointInfo class holds information for break points set in a
|
||||
// function. The DebugInfo object holds a BreakPointInfo object for each code
|
||||
// position with one or more break points.
|
||||
class BreakPointInfo : public Tuple2 {
|
||||
public:
|
||||
// The position in the source for the break position.
|
||||
DECL_INT_ACCESSORS(source_position)
|
||||
// List of related JavaScript break points.
|
||||
DECL_ACCESSORS(break_point_objects, Object)
|
||||
|
||||
// Removes a break point.
|
||||
static void ClearBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Set a break point.
|
||||
static void SetBreakPoint(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Check if break point info has this break point object.
|
||||
static bool HasBreakPointObject(Handle<BreakPointInfo> info,
|
||||
Handle<Object> break_point_object);
|
||||
// Get the number of break points for this code offset.
|
||||
int GetBreakPointCount();
|
||||
|
||||
int GetStatementPosition(Handle<DebugInfo> debug_info);
|
||||
|
||||
DECLARE_CAST(BreakPointInfo)
|
||||
|
||||
static const int kSourcePositionIndex = kValue1Offset;
|
||||
static const int kBreakPointObjectsIndex = kValue2Offset;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_OBJECTS_DEBUG_OBJECTS_H_
|
@ -2,9 +2,58 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#undef CAST_ACCESSOR
|
||||
#undef DECL_BOOLEAN_ACCESSORS
|
||||
#undef DECL_INT_ACCESSORS
|
||||
#undef DECL_ACCESSORS
|
||||
#undef DECLARE_CAST
|
||||
#undef CAST_ACCESSOR
|
||||
#undef INT_ACCESSORS
|
||||
#undef ACCESSORS_CHECKED2
|
||||
#undef ACCESSORS_CHECKED
|
||||
#undef ACCESSORS
|
||||
#undef SMI_ACCESSORS_CHECKED
|
||||
#undef SMI_ACCESSORS
|
||||
#undef SYNCHRONIZED_SMI_ACCESSORS
|
||||
#undef NOBARRIER_SMI_ACCESSORS
|
||||
#undef BOOL_GETTER
|
||||
#undef BOOL_ACCESSORS
|
||||
#undef TYPE_CHECKER
|
||||
#undef FIELD_ADDR
|
||||
#undef FIELD_ADDR_CONST
|
||||
#undef READ_FIELD
|
||||
#undef ACQUIRE_READ_FIELD
|
||||
#undef NOBARRIER_READ_FIELD
|
||||
#undef WRITE_FIELD
|
||||
#undef RELEASE_WRITE_FIELD
|
||||
#undef NOBARRIER_WRITE_FIELD
|
||||
#undef WRITE_BARRIER
|
||||
#undef CONDITIONAL_WRITE_BARRIER
|
||||
#undef READ_DOUBLE_FIELD
|
||||
#undef WRITE_DOUBLE_FIELD
|
||||
#undef READ_INT_FIELD
|
||||
#undef WRITE_INT_FIELD
|
||||
#undef READ_INTPTR_FIELD
|
||||
#undef WRITE_INTPTR_FIELD
|
||||
#undef READ_UINT8_FIELD
|
||||
#undef WRITE_UINT8_FIELD
|
||||
#undef READ_INT8_FIELD
|
||||
#undef WRITE_INT8_FIELD
|
||||
#undef READ_UINT16_FIELD
|
||||
#undef WRITE_UINT16_FIELD
|
||||
#undef READ_INT16_FIELD
|
||||
#undef WRITE_INT16_FIELD
|
||||
#undef READ_UINT32_FIELD
|
||||
#undef WRITE_UINT32_FIELD
|
||||
#undef READ_INT32_FIELD
|
||||
#undef WRITE_INT32_FIELD
|
||||
#undef READ_FLOAT_FIELD
|
||||
#undef WRITE_FLOAT_FIELD
|
||||
#undef READ_UINT64_FIELD
|
||||
#undef WRITE_UINT64_FIELD
|
||||
#undef READ_INT64_FIELD
|
||||
#undef WRITE_INT64_FIELD
|
||||
#undef READ_BYTE_FIELD
|
||||
#undef NOBARRIER_READ_BYTE_FIELD
|
||||
#undef WRITE_BYTE_FIELD
|
||||
#undef NOBARRIER_WRITE_BYTE_FIELD
|
||||
#undef DECLARE_VERIFIER
|
||||
|
@ -35,6 +35,212 @@
|
||||
return reinterpret_cast<const type*>(object); \
|
||||
}
|
||||
|
||||
#define INT_ACCESSORS(holder, name, offset) \
|
||||
int holder::name() const { return READ_INT_FIELD(this, offset); } \
|
||||
void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
|
||||
|
||||
#define ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
|
||||
set_condition) \
|
||||
type* holder::name() const { \
|
||||
DCHECK(get_condition); \
|
||||
return type::cast(READ_FIELD(this, offset)); \
|
||||
} \
|
||||
void holder::set_##name(type* value, WriteBarrierMode mode) { \
|
||||
DCHECK(set_condition); \
|
||||
WRITE_FIELD(this, offset, value); \
|
||||
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
|
||||
}
|
||||
#define ACCESSORS_CHECKED(holder, name, type, offset, condition) \
|
||||
ACCESSORS_CHECKED2(holder, name, type, offset, condition, condition)
|
||||
|
||||
#define ACCESSORS(holder, name, type, offset) \
|
||||
ACCESSORS_CHECKED(holder, name, type, offset, true)
|
||||
|
||||
// Getter that returns a Smi as an int and writes an int as a Smi.
|
||||
#define SMI_ACCESSORS_CHECKED(holder, name, offset, condition) \
|
||||
int holder::name() const { \
|
||||
DCHECK(condition); \
|
||||
Object* value = READ_FIELD(this, offset); \
|
||||
return Smi::cast(value)->value(); \
|
||||
} \
|
||||
void holder::set_##name(int value) { \
|
||||
DCHECK(condition); \
|
||||
WRITE_FIELD(this, offset, Smi::FromInt(value)); \
|
||||
}
|
||||
|
||||
#define SMI_ACCESSORS(holder, name, offset) \
|
||||
SMI_ACCESSORS_CHECKED(holder, name, offset, true)
|
||||
|
||||
#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
|
||||
int holder::synchronized_##name() const { \
|
||||
Object* value = ACQUIRE_READ_FIELD(this, offset); \
|
||||
return Smi::cast(value)->value(); \
|
||||
} \
|
||||
void holder::synchronized_set_##name(int value) { \
|
||||
RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
|
||||
}
|
||||
|
||||
#define NOBARRIER_SMI_ACCESSORS(holder, name, offset) \
|
||||
int holder::nobarrier_##name() const { \
|
||||
Object* value = NOBARRIER_READ_FIELD(this, offset); \
|
||||
return Smi::cast(value)->value(); \
|
||||
} \
|
||||
void holder::nobarrier_set_##name(int value) { \
|
||||
NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
|
||||
}
|
||||
|
||||
#define BOOL_GETTER(holder, field, name, offset) \
|
||||
bool holder::name() const { return BooleanBit::get(field(), offset); }
|
||||
|
||||
#define BOOL_ACCESSORS(holder, field, name, offset) \
|
||||
bool holder::name() const { return BooleanBit::get(field(), offset); } \
|
||||
void holder::set_##name(bool value) { \
|
||||
set_##field(BooleanBit::set(field(), offset, value)); \
|
||||
}
|
||||
|
||||
#define TYPE_CHECKER(type, instancetype) \
|
||||
bool HeapObject::Is##type() const { \
|
||||
return map()->instance_type() == instancetype; \
|
||||
}
|
||||
|
||||
#define FIELD_ADDR(p, offset) \
|
||||
(reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
|
||||
|
||||
#define FIELD_ADDR_CONST(p, offset) \
|
||||
(reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
|
||||
|
||||
#define READ_FIELD(p, offset) \
|
||||
(*reinterpret_cast<Object* const*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define ACQUIRE_READ_FIELD(p, offset) \
|
||||
reinterpret_cast<Object*>(base::Acquire_Load( \
|
||||
reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
|
||||
|
||||
#define NOBARRIER_READ_FIELD(p, offset) \
|
||||
reinterpret_cast<Object*>(base::NoBarrier_Load( \
|
||||
reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
|
||||
|
||||
#ifdef V8_CONCURRENT_MARKING
|
||||
#define WRITE_FIELD(p, offset, value) \
|
||||
base::NoBarrier_Store( \
|
||||
reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
|
||||
reinterpret_cast<base::AtomicWord>(value));
|
||||
#else
|
||||
#define WRITE_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
|
||||
#endif
|
||||
|
||||
#define RELEASE_WRITE_FIELD(p, offset, value) \
|
||||
base::Release_Store( \
|
||||
reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
|
||||
reinterpret_cast<base::AtomicWord>(value));
|
||||
|
||||
#define NOBARRIER_WRITE_FIELD(p, offset, value) \
|
||||
base::NoBarrier_Store( \
|
||||
reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
|
||||
reinterpret_cast<base::AtomicWord>(value));
|
||||
|
||||
#define WRITE_BARRIER(heap, object, offset, value) \
|
||||
heap->incremental_marking()->RecordWrite( \
|
||||
object, HeapObject::RawField(object, offset), value); \
|
||||
heap->RecordWrite(object, offset, value);
|
||||
|
||||
#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
|
||||
if (mode != SKIP_WRITE_BARRIER) { \
|
||||
if (mode == UPDATE_WRITE_BARRIER) { \
|
||||
heap->incremental_marking()->RecordWrite( \
|
||||
object, HeapObject::RawField(object, offset), value); \
|
||||
} \
|
||||
heap->RecordWrite(object, offset, value); \
|
||||
}
|
||||
|
||||
#define READ_DOUBLE_FIELD(p, offset) \
|
||||
ReadDoubleValue(FIELD_ADDR_CONST(p, offset))
|
||||
|
||||
#define WRITE_DOUBLE_FIELD(p, offset, value) \
|
||||
WriteDoubleValue(FIELD_ADDR(p, offset), value)
|
||||
|
||||
#define READ_INT_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INTPTR_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const intptr_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INTPTR_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT8_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint8_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT8_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint8_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT8_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int8_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT8_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int8_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT16_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint16_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT16_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT16_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int16_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT16_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int16_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT32_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint32_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT32_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT32_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT32_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_FLOAT_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const float*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_FLOAT_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<float*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_UINT64_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const uint64_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_UINT64_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint64_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT64_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define WRITE_INT64_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_BYTE_FIELD(p, offset) \
|
||||
(*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
|
||||
|
||||
#define NOBARRIER_READ_BYTE_FIELD(p, offset) \
|
||||
static_cast<byte>(base::NoBarrier_Load( \
|
||||
reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset))))
|
||||
|
||||
#define WRITE_BYTE_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value) \
|
||||
base::NoBarrier_Store( \
|
||||
reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
|
||||
static_cast<base::Atomic8>(value));
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
#define DECLARE_VERIFIER(Name) void Name##Verify();
|
||||
#else
|
||||
|
@ -1224,6 +1224,9 @@
|
||||
'objects/code-cache-inl.h',
|
||||
'objects/compilation-cache.h',
|
||||
'objects/compilation-cache-inl.h',
|
||||
'objects/debug-objects-inl.h',
|
||||
'objects/debug-objects.cc',
|
||||
'objects/debug-objects.h',
|
||||
'objects/descriptor-array.h',
|
||||
'objects/dictionary.h',
|
||||
'objects/frame-array.h',
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/compiler/wasm-compiler.h"
|
||||
#include "src/debug/debug-interface.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/wasm/module-decoder.h"
|
||||
#include "src/wasm/wasm-code-specialization.h"
|
||||
#include "src/wasm/wasm-module.h"
|
||||
|
Loading…
Reference in New Issue
Block a user