[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:
jgruber 2017-05-23 05:17:09 -07:00 committed by Commit bot
parent 9dbafbd5d3
commit d74ece4180
19 changed files with 753 additions and 679 deletions

View File

@ -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",

View File

@ -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);

View File

@ -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();

View File

@ -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"

View File

@ -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"

View File

@ -17,8 +17,10 @@
namespace v8 {
namespace internal {
class BreakPointInfo;
class BoilerplateDescription;
class ConstantElementsPair;
class DebugInfo;
enum FunctionMode {
// With prototype.

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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) {

View File

@ -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)

View 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_

View 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
View 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_

View File

@ -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

View File

@ -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

View File

@ -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',

View File

@ -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"