📄 objects-debug.cc.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "disassembler.h"#include "disasm.h"#include "macro-assembler.h"namespace v8 { namespace internal {#ifdef DEBUGstatic const char* TypeToString(InstanceType type);void Object::Print() { if (IsSmi()) { Smi::cast(this)->SmiPrint(); } else if (IsFailure()) { Failure::cast(this)->FailurePrint(); } else { HeapObject::cast(this)->HeapObjectPrint(); } Flush();}void Object::PrintLn() { Print(); PrintF("\n");}void Object::Verify() { if (IsSmi()) { Smi::cast(this)->SmiVerify(); } else if (IsFailure()) { Failure::cast(this)->FailureVerify(); } else { HeapObject::cast(this)->HeapObjectVerify(); }}void Object::VerifyPointer(Object* p) { if (p->IsHeapObject()) { HeapObject::VerifyHeapPointer(p); } else { ASSERT(p->IsSmi()); }}void Smi::SmiVerify() { ASSERT(IsSmi());}void Failure::FailureVerify() { ASSERT(IsFailure());}void HeapObject::PrintHeader(const char* id) { PrintF("%p: [%s]\n", this, id);}void HeapObject::HeapObjectPrint() { InstanceType instance_type = map()->instance_type(); HandleScope scope; if (instance_type < FIRST_NONSTRING_TYPE) { String::cast(this)->StringPrint(); return; } switch (instance_type) { case MAP_TYPE: Map::cast(this)->MapPrint(); break; case HEAP_NUMBER_TYPE: HeapNumber::cast(this)->HeapNumberPrint(); break; case FIXED_ARRAY_TYPE: FixedArray::cast(this)->FixedArrayPrint(); break; case BYTE_ARRAY_TYPE: ByteArray::cast(this)->ByteArrayPrint(); break; case FILLER_TYPE: PrintF("filler"); break; case JS_OBJECT_TYPE: // fall through case JS_ARRAY_TYPE: case JS_REGEXP_TYPE: JSObject::cast(this)->JSObjectPrint(); break; case ODDBALL_TYPE: Oddball::cast(this)->to_string()->Print(); break; case JS_FUNCTION_TYPE: JSFunction::cast(this)->JSFunctionPrint(); break; case JS_GLOBAL_OBJECT_TYPE: JSGlobalObject::cast(this)->JSGlobalObjectPrint(); break; case JS_BUILTINS_OBJECT_TYPE: JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(); break; case JS_VALUE_TYPE: PrintF("Value wrapper around:"); JSValue::cast(this)->value()->Print(); break; case CODE_TYPE: Code::cast(this)->CodePrint(); break; case PROXY_TYPE: Proxy::cast(this)->ProxyPrint(); break; case SHARED_FUNCTION_INFO_TYPE: SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(); break;#define MAKE_STRUCT_CASE(NAME, Name, name) \ case NAME##_TYPE: \ Name::cast(this)->Name##Print(); \ break; STRUCT_LIST(MAKE_STRUCT_CASE)#undef MAKE_STRUCT_CASE default: PrintF("UNKNOWN TYPE %d", map()->instance_type()); UNREACHABLE(); break; }}void HeapObject::HeapObjectVerify() { InstanceType instance_type = map()->instance_type(); if (instance_type < FIRST_NONSTRING_TYPE) { String::cast(this)->StringVerify(); return; } switch (instance_type) { case MAP_TYPE: Map::cast(this)->MapVerify(); break; case HEAP_NUMBER_TYPE: HeapNumber::cast(this)->HeapNumberVerify(); break; case FIXED_ARRAY_TYPE: FixedArray::cast(this)->FixedArrayVerify(); break; case BYTE_ARRAY_TYPE: ByteArray::cast(this)->ByteArrayVerify(); break; case CODE_TYPE: Code::cast(this)->CodeVerify(); break; case ODDBALL_TYPE: Oddball::cast(this)->OddballVerify(); break; case JS_OBJECT_TYPE: JSObject::cast(this)->JSObjectVerify(); break; case JS_VALUE_TYPE: JSValue::cast(this)->JSValueVerify(); break; case JS_FUNCTION_TYPE: JSFunction::cast(this)->JSFunctionVerify(); break; case JS_GLOBAL_OBJECT_TYPE: JSGlobalObject::cast(this)->JSGlobalObjectVerify(); break; case JS_BUILTINS_OBJECT_TYPE: JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify(); break; case JS_ARRAY_TYPE: JSArray::cast(this)->JSArrayVerify(); break; case JS_REGEXP_TYPE: JSRegExp::cast(this)->JSRegExpVerify(); break; case FILLER_TYPE: break; case PROXY_TYPE: Proxy::cast(this)->ProxyVerify(); break; case SHARED_FUNCTION_INFO_TYPE: SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify(); break;#define MAKE_STRUCT_CASE(NAME, Name, name) \ case NAME##_TYPE: \ Name::cast(this)->Name##Verify(); \ break; STRUCT_LIST(MAKE_STRUCT_CASE)#undef MAKE_STRUCT_CASE default: UNREACHABLE(); break; }}void HeapObject::VerifyHeapPointer(Object* p) { ASSERT(p->IsHeapObject()); ASSERT(Heap::Contains(HeapObject::cast(p)));}void HeapNumber::HeapNumberVerify() { ASSERT(IsHeapNumber());}void ByteArray::ByteArrayPrint() { PrintF("byte array, data starts at %p", GetDataStartAddress());}void ByteArray::ByteArrayVerify() { ASSERT(IsByteArray());}void JSObject::PrintProperties() { if (HasFastProperties()) { for (DescriptorReader r(map()->instance_descriptors()); !r.eos(); r.advance()) { PrintF(" "); r.GetKey()->StringPrint(); PrintF(": "); if (r.type() == FIELD) { properties()->get(r.GetFieldIndex())->ShortPrint(); PrintF(" (field at offset %d)\n", r.GetFieldIndex()); } else if (r.type() == CONSTANT_FUNCTION) { r.GetConstantFunction()->ShortPrint(); PrintF(" (constant function)\n"); } else if (r.type() == CALLBACKS) { r.GetCallbacksObject()->ShortPrint(); PrintF(" (callback)\n"); } else if (r.type() == MAP_TRANSITION) { PrintF(" (map transition)\n"); } else { UNREACHABLE(); } } } else { property_dictionary()->Print(); }}void JSObject::PrintElements() { if (HasFastElements()) { FixedArray* p = FixedArray::cast(elements()); for (int i = 0; i < p->length(); i++) { PrintF(" %d: ", i); p->get(i)->ShortPrint(); PrintF("\n"); } } else { elements()->Print(); }}void JSObject::JSObjectPrint() { PrintF("%p: [JSObject]\n", this); PrintF(" - map = %p\n", map()); PrintF(" - prototype = %p\n", GetPrototype()); PrintF(" {\n"); PrintProperties(); PrintElements(); PrintF(" }\n");}void JSObject::JSObjectVerify() { VerifyHeapPointer(properties()); VerifyHeapPointer(elements()); if (HasFastProperties()) { CHECK(map()->unused_property_fields() == (properties()->length() - map()->NextFreePropertyIndex())); }}static const char* TypeToString(InstanceType type) { switch (type) { case MAP_TYPE: return "MAP"; case HEAP_NUMBER_TYPE: return "HEAP_NUMBER"; case SHORT_SYMBOL_TYPE: case MEDIUM_SYMBOL_TYPE: case LONG_SYMBOL_TYPE: return "SYMBOL"; case SHORT_ASCII_SYMBOL_TYPE: case MEDIUM_ASCII_SYMBOL_TYPE: case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL"; case SHORT_SLICED_SYMBOL_TYPE: case MEDIUM_SLICED_SYMBOL_TYPE: case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL"; case SHORT_SLICED_ASCII_SYMBOL_TYPE: case MEDIUM_SLICED_ASCII_SYMBOL_TYPE: case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL"; case SHORT_CONS_SYMBOL_TYPE: case MEDIUM_CONS_SYMBOL_TYPE: case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL"; case SHORT_CONS_ASCII_SYMBOL_TYPE: case MEDIUM_CONS_ASCII_SYMBOL_TYPE: case LONG_CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL"; case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE: case MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE: case LONG_EXTERNAL_ASCII_SYMBOL_TYPE: case SHORT_EXTERNAL_SYMBOL_TYPE: case MEDIUM_EXTERNAL_SYMBOL_TYPE: case LONG_EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL"; case SHORT_ASCII_STRING_TYPE: case MEDIUM_ASCII_STRING_TYPE: case LONG_ASCII_STRING_TYPE: return "ASCII_STRING"; case SHORT_STRING_TYPE: case MEDIUM_STRING_TYPE: case LONG_STRING_TYPE: return "TWO_BYTE_STRING"; case SHORT_CONS_STRING_TYPE: case MEDIUM_CONS_STRING_TYPE: case LONG_CONS_STRING_TYPE: case SHORT_CONS_ASCII_STRING_TYPE: case MEDIUM_CONS_ASCII_STRING_TYPE: case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING"; case SHORT_SLICED_STRING_TYPE: case MEDIUM_SLICED_STRING_TYPE: case LONG_SLICED_STRING_TYPE: case SHORT_SLICED_ASCII_STRING_TYPE: case MEDIUM_SLICED_ASCII_STRING_TYPE: case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING"; case SHORT_EXTERNAL_ASCII_STRING_TYPE: case MEDIUM_EXTERNAL_ASCII_STRING_TYPE: case LONG_EXTERNAL_ASCII_STRING_TYPE: case SHORT_EXTERNAL_STRING_TYPE: case MEDIUM_EXTERNAL_STRING_TYPE: case LONG_EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING"; case FIXED_ARRAY_TYPE: return "FIXED_ARRAY"; case BYTE_ARRAY_TYPE: return "BYTE_ARRAY"; case FILLER_TYPE: return "FILLER"; case JS_OBJECT_TYPE: return "JS_OBJECT"; case ODDBALL_TYPE: return "ODDBALL"; case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO"; case JS_FUNCTION_TYPE: return "JS_FUNCTION"; case CODE_TYPE: return "CODE"; case JS_ARRAY_TYPE: return "JS_ARRAY"; case JS_REGEXP_TYPE: return "JS_REGEXP"; case JS_VALUE_TYPE: return "JS_VALUE"; case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT"; case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT"; case PROXY_TYPE: return "PROXY"; case SMI_TYPE: return "SMI";#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME; STRUCT_LIST(MAKE_STRUCT_CASE)#undef MAKE_STRUCT_CASE } return "UNKNOWN";}void Map::MapPrint() { HeapObject::PrintHeader("Map"); PrintF(" - type: %s\n", TypeToString(instance_type())); PrintF(" - instance size: %d\n", instance_size()); PrintF(" - unused property fields: %d\n", unused_property_fields()); PrintF(" - instance descriptors: "); instance_descriptors()->ShortPrint(); PrintF("\n - prototype: "); prototype()->ShortPrint(); PrintF("\n - constructor: "); constructor()->ShortPrint(); PrintF("\n");}void Map::MapVerify() { ASSERT(!Heap::InNewSpace(this)); ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); ASSERT(kPointerSize <= instance_size() && instance_size() < Heap::Capacity()); VerifyHeapPointer(prototype()); VerifyHeapPointer(instance_descriptors());}void FixedArray::FixedArrayPrint() { HeapObject::PrintHeader("FixedArray"); PrintF(" - length: %d", length()); for (int i = 0; i < length(); i++) { PrintF("\n [%d]: ", i); get(i)->ShortPrint(); } PrintF("\n");}void FixedArray::FixedArrayVerify() { for (int i = 0; i < length(); i++) { Object* e = get(i); if (e->IsHeapObject()) { VerifyHeapPointer(e); } else { e->Verify(); } }}void JSValue::JSValuePrint() { HeapObject::PrintHeader("ValueObject"); value()->Print();}void JSValue::JSValueVerify() { Object* v = value(); if (v->IsHeapObject()) { VerifyHeapPointer(v); }}void String::StringPrint() { if (IsSymbol()) { PrintF("#"); } else if (IsConsString()) { PrintF("c\""); } else { PrintF("\""); } for (int i = 0; i < length(); i++) { PrintF("%c", Get(i)); } if (!IsSymbol()) PrintF("\"");}void String::StringVerify() { CHECK(IsString()); CHECK(length() >= 0 && length() <= Smi::kMaxValue); if (IsSymbol()) { CHECK(!Heap::InNewSpace(this)); }}void JSFunction::JSFunctionPrint() { HeapObject::PrintHeader("Function"); PrintF(" - map = 0x%p\n", map()); PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no"); PrintF(" - initial_map = "); if (has_initial_map()) { initial_map()->ShortPrint(); } PrintF("\n - shared_info = "); shared()->ShortPrint(); PrintF("\n - name = "); shared()->name()->Print(); PrintF("\n - context = "); unchecked_context()->ShortPrint(); PrintF("\n - code = "); code()->ShortPrint(); PrintF("\n"); PrintProperties(); PrintElements(); PrintF("\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -