📄 objects-inl.h.svn-base
字号:
}bool Dictionary::requires_slow_elements() { Object* max_index_object = get(kPrefixStartIndex); if (!max_index_object->IsSmi()) return false; return 0 != (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);}uint32_t Dictionary::max_number_key() { ASSERT(!requires_slow_elements()); Object* max_index_object = get(kPrefixStartIndex); if (!max_index_object->IsSmi()) return 0; uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value()); return value >> kRequiresSlowElementsTagSize;}// ------------------------------------// Cast operationsCAST_ACCESSOR(FixedArray)CAST_ACCESSOR(DescriptorArray)CAST_ACCESSOR(Dictionary)CAST_ACCESSOR(SymbolTable)CAST_ACCESSOR(CompilationCacheTable)CAST_ACCESSOR(MapCache)CAST_ACCESSOR(String)CAST_ACCESSOR(SeqString)CAST_ACCESSOR(AsciiString)CAST_ACCESSOR(TwoByteString)CAST_ACCESSOR(ConsString)CAST_ACCESSOR(SlicedString)CAST_ACCESSOR(ExternalString)CAST_ACCESSOR(ExternalAsciiString)CAST_ACCESSOR(ExternalTwoByteString)CAST_ACCESSOR(JSObject)CAST_ACCESSOR(Smi)CAST_ACCESSOR(Failure)CAST_ACCESSOR(HeapObject)CAST_ACCESSOR(HeapNumber)CAST_ACCESSOR(Oddball)CAST_ACCESSOR(SharedFunctionInfo)CAST_ACCESSOR(Map)CAST_ACCESSOR(JSFunction)CAST_ACCESSOR(JSGlobalObject)CAST_ACCESSOR(JSBuiltinsObject)CAST_ACCESSOR(Code)CAST_ACCESSOR(JSArray)CAST_ACCESSOR(JSRegExp)CAST_ACCESSOR(Proxy)CAST_ACCESSOR(ByteArray)CAST_ACCESSOR(Struct)#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) STRUCT_LIST(MAKE_STRUCT_CAST)#undef MAKE_STRUCT_CASTtemplate <int prefix_size, int elem_size>HashTable<prefix_size, elem_size>* HashTable<prefix_size, elem_size>::cast( Object* obj) { ASSERT(obj->IsHashTable()); return reinterpret_cast<HashTable*>(obj);}INT_ACCESSORS(Array, length, kLengthOffset)bool String::Equals(String* other) { if (other == this) return true; if (IsSymbol() && other->IsSymbol()) return false; return SlowEquals(other);}int String::length() { uint32_t len = READ_INT_FIELD(this, kLengthOffset); switch (size_tag()) { case kShortStringTag: return len >> kShortLengthShift; case kMediumStringTag: return len >> kMediumLengthShift; case kLongStringTag: return len >> kLongLengthShift; default: break; } UNREACHABLE(); return 0;}void String::set_length(int value) { switch (size_tag()) { case kShortStringTag: WRITE_INT_FIELD(this, kLengthOffset, value << kShortLengthShift); break; case kMediumStringTag: WRITE_INT_FIELD(this, kLengthOffset, value << kMediumLengthShift); break; case kLongStringTag: WRITE_INT_FIELD(this, kLengthOffset, value << kLongLengthShift); break; default: UNREACHABLE(); break; }}int String::length_field() { return READ_INT_FIELD(this, kLengthOffset);}void String::set_length_field(int value) { WRITE_INT_FIELD(this, kLengthOffset, value);}void String::TryFlatten() { // We don't need to flatten strings that are already flat. Since this code // is inlined, it can be helpful in the flat case to not call out to Flatten. StringRepresentationTag str_type = representation_tag(); if (str_type != kSeqStringTag && str_type != kExternalStringTag) { Flatten(); }}uint16_t String::Get(int index) { ASSERT(index >= 0 && index < length()); switch (representation_tag()) { case kSeqStringTag: return is_ascii() ? AsciiString::cast(this)->AsciiStringGet(index) : TwoByteString::cast(this)->TwoByteStringGet(index); case kConsStringTag: return ConsString::cast(this)->ConsStringGet(index); case kSlicedStringTag: return SlicedString::cast(this)->SlicedStringGet(index); case kExternalStringTag: return is_ascii() ? ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index) : ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); default: break; } UNREACHABLE(); return 0;}void String::Set(int index, uint16_t value) { ASSERT(index >= 0 && index < length()); ASSERT(IsSeqString()); return is_ascii() ? AsciiString::cast(this)->AsciiStringSet(index, value) : TwoByteString::cast(this)->TwoByteStringSet(index, value);}bool String::IsAscii() { return is_ascii();}bool String::StringIsConsString() { return representation_tag() == kConsStringTag;}bool String::StringIsSlicedString() { return representation_tag() == kSlicedStringTag;}uint32_t String::size_tag() { return map_size_tag(map());}uint32_t String::map_size_tag(Map* map) { return map->instance_type() & kStringSizeMask;}bool String::is_symbol() { return is_symbol_map(map());}bool String::is_symbol_map(Map* map) { return (map->instance_type() & kIsSymbolMask) != 0;}bool String::is_ascii() { return is_ascii_map(map());}bool String::is_ascii_map(Map* map) { return (map->instance_type() & kStringEncodingMask) != 0;}StringRepresentationTag String::representation_tag() { return map_representation_tag(map());}StringRepresentationTag String::map_representation_tag(Map* map) { uint32_t tag = map->instance_type() & kStringRepresentationMask; return static_cast<StringRepresentationTag>(tag);}bool String::IsFlat() { String* current = this; while (true) { switch (current->representation_tag()) { case kConsStringTag: return String::cast(ConsString::cast(current)->second())->length() == 0; case kSlicedStringTag: current = String::cast(SlicedString::cast(this)->buffer()); break; default: return true; } }}uint16_t AsciiString::AsciiStringGet(int index) { ASSERT(index >= 0 && index < length()); return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);}void AsciiString::AsciiStringSet(int index, uint16_t value) { ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, static_cast<byte>(value));}Address AsciiString::GetCharsAddress() { return FIELD_ADDR(this, kHeaderSize);}uint16_t TwoByteString::TwoByteStringGet(int index) { ASSERT(index >= 0 && index < length()); return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);}void TwoByteString::TwoByteStringSet(int index, uint16_t value) { ASSERT(index >= 0 && index < length()); WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);}int TwoByteString::TwoByteStringSize(Map* map) { uint32_t length = READ_INT_FIELD(this, kLengthOffset); // Use the map (and not 'this') to compute the size tag, since // TwoByteStringSize is called during GC when maps are encoded. switch (map_size_tag(map)) { case kShortStringTag: length = length >> kShortLengthShift; break; case kMediumStringTag: length = length >> kMediumLengthShift; break; case kLongStringTag: length = length >> kLongLengthShift; break; default: break; } return SizeFor(length);}int AsciiString::AsciiStringSize(Map* map) { uint32_t length = READ_INT_FIELD(this, kLengthOffset); // Use the map (and not 'this') to compute the size tag, since // AsciiStringSize is called during GC when maps are encoded. switch (map_size_tag(map)) { case kShortStringTag: length = length >> kShortLengthShift; break; case kMediumStringTag: length = length >> kMediumLengthShift; break; case kLongStringTag: length = length >> kLongLengthShift; break; default: break; } return SizeFor(length);}Object* ConsString::first() { return READ_FIELD(this, kFirstOffset);}void ConsString::set_first(Object* value) { WRITE_FIELD(this, kFirstOffset, value); WRITE_BARRIER(this, kFirstOffset);}Object* ConsString::second() { return READ_FIELD(this, kSecondOffset);}void ConsString::set_second(Object* value) { WRITE_FIELD(this, kSecondOffset, value); WRITE_BARRIER(this, kSecondOffset);}Object* SlicedString::buffer() { return READ_FIELD(this, kBufferOffset);}void SlicedString::set_buffer(Object* buffer) { WRITE_FIELD(this, kBufferOffset, buffer); WRITE_BARRIER(this, kBufferOffset);}int SlicedString::start() { return READ_INT_FIELD(this, kStartOffset);}void SlicedString::set_start(int start) { WRITE_INT_FIELD(this, kStartOffset, start);}ExternalAsciiString::Resource* ExternalAsciiString::resource() { return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));}void ExternalAsciiString::set_resource( ExternalAsciiString::Resource* resource) { *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;}ExternalTwoByteString::Resource* ExternalTwoByteString::resource() { return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));}void ExternalTwoByteString::set_resource( ExternalTwoByteString::Resource* resource) { *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;}byte ByteArray::get(int index) { ASSERT(index >= 0 && index < this->length()); return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);}void ByteArray::set(int index, byte value) { ASSERT(index >= 0 && index < this->length()); WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);}int ByteArray::get_int(int index) { ASSERT(index >= 0 && (index * kIntSize) < this->length()); return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);}ByteArray* ByteArray::FromDataStartAddress(Address address) { ASSERT_TAG_ALIGNED(address); return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);}Address ByteArray::GetDataStartAddress() { return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;}int Map::instance_size() { return READ_BYTE_FIELD(this, kInstanceSizeOffset);}int HeapObject::SizeFromMap(Map* map) { InstanceType instance_type = map->instance_type(); // Only inline the two most frequent cases. if (instance_type == JS_OBJECT_TYPE) return map->instance_size(); if (instance_type == FIXED_ARRAY_TYPE) { return reinterpret_cast<FixedArray*>(this)->FixedArraySize(); } // Otherwise do the general size computation. return SlowSizeFromMap(map);}void Map::set_instance_size(int value) { ASSERT(0 <= value && value < 256); WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));}InstanceType Map::instance_type() { return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));}void Map::set_instance_type(InstanceType value) { ASSERT(0 <= value && value < 256); WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);}int Map::unused_property_fields() { return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);}void Map::set_unused_property_fields(int value) { WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));}byte Map::bit_field() { return READ_BYTE_FIELD(this, kBitFieldOffset);}void Map::set_bit_field(byte value) { WRITE_BYTE_FIELD(this, kBitFieldOffset, value);}void Map::set_non_instance_prototype(bool value) { if (value) { set_bit_field(bit_field() | (1 << kHasNonInstancePrototype)); } else { set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype)); }}bool Map::has_non_instance_prototype() { return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;}Code::Flags Code::flags() { return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));}void Code::set_flags(Code::Flags flags) { // Make sure that all call stubs have an arguments count. ASSERT(ExtractKindFromFlags(flags) != CALL_IC || ExtractArgumentsCountFromFlags(flags) >= 0); WRITE_INT_FIELD(this, kFlagsOffset, flags);}Code::Kind Code::kind() { return ExtractKindFromFlags(flags());}InlineCacheState Code::ic_state() { InlineCacheState result = ExtractICStateFromFlags(flags()); // Only allow uninitialized or debugger states for non-IC code // objects. This is used in the debugger to determine whether or not // a call to code object has been replaced with a debug break call. ASSERT(is_inline_cache_stub() || result == UNINITIALIZED || result == DEBUG_BREAK || result == DEBUG_PREPARE_STEP_IN); return result;}PropertyType Code::type() { ASSERT(ic_state() == MONOMORPHIC); return ExtractTypeFromFlags(flags());}int Code::arguments_count() { ASSERT(is_call_stub() || kind() == STUB); return ExtractArgumentsCountFromFlags(flags());}CodeStub::Major Code::major_key() { ASSERT(kind() == STUB); return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this, kStubMajorKeyOffset));}void Code::set_major_key(CodeStub::Major major) { ASSERT(kind() == STUB); ASSERT(0 <= major && major < 256); WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);}bool Code::is_inline_cache_stub() { Kind kind = this->kind(); return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;}Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state, PropertyType type,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -