⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
  InstanceType instance_type = map->instance_type();  if (instance_type < FIRST_NONSTRING_TYPE      && (reinterpret_cast<String*>(this)->map_representation_tag(map)          == kSeqStringTag)) {    if (reinterpret_cast<String*>(this)->is_ascii_map(map)) {      return reinterpret_cast<AsciiString*>(this)->AsciiStringSize(map);    } else {      return reinterpret_cast<TwoByteString*>(this)->TwoByteStringSize(map);    }  }  switch (instance_type) {    case FIXED_ARRAY_TYPE:      return reinterpret_cast<FixedArray*>(this)->FixedArraySize();    case BYTE_ARRAY_TYPE:      return reinterpret_cast<ByteArray*>(this)->ByteArraySize();    case CODE_TYPE:      return reinterpret_cast<Code*>(this)->CodeSize();    case MAP_TYPE:      return Map::kSize;    default:      return map->instance_size();  }}void HeapObject::Iterate(ObjectVisitor* v) {  // Handle header  IteratePointer(v, kMapOffset);  // Handle object body  Map* m = map();  IterateBody(m->instance_type(), SizeFromMap(m), v);}void HeapObject::IterateBody(InstanceType type, int object_size,                             ObjectVisitor* v) {  // Avoiding <Type>::cast(this) because it accesses the map pointer field.  // During GC, the map pointer field is encoded.  if (type < FIRST_NONSTRING_TYPE) {    switch (type & kStringRepresentationMask) {      case kSeqStringTag:        break;      case kConsStringTag:        reinterpret_cast<ConsString*>(this)->ConsStringIterateBody(v);        break;      case kSlicedStringTag:        reinterpret_cast<SlicedString*>(this)->SlicedStringIterateBody(v);        break;    }    return;  }  switch (type) {    case FIXED_ARRAY_TYPE:      reinterpret_cast<FixedArray*>(this)->FixedArrayIterateBody(v);      break;    case JS_OBJECT_TYPE:    case JS_VALUE_TYPE:    case JS_ARRAY_TYPE:    case JS_REGEXP_TYPE:    case JS_FUNCTION_TYPE:    case JS_GLOBAL_OBJECT_TYPE:      reinterpret_cast<JSObject*>(this)->JSObjectIterateBody(object_size, v);      break;    case JS_BUILTINS_OBJECT_TYPE:      reinterpret_cast<JSObject*>(this)->JSObjectIterateBody(object_size, v);      break;    case ODDBALL_TYPE:      reinterpret_cast<Oddball*>(this)->OddballIterateBody(v);      break;    case PROXY_TYPE:      reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v);      break;    case MAP_TYPE:      reinterpret_cast<Map*>(this)->MapIterateBody(v);      break;    case CODE_TYPE:      reinterpret_cast<Code*>(this)->CodeIterateBody(v);      break;    case HEAP_NUMBER_TYPE:    case FILLER_TYPE:    case BYTE_ARRAY_TYPE:      break;    case SHARED_FUNCTION_INFO_TYPE: {      SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this);      shared->SharedFunctionInfoIterateBody(v);      break;    }#define MAKE_STRUCT_CASE(NAME, Name, name) \        case NAME##_TYPE:      STRUCT_LIST(MAKE_STRUCT_CASE)#undef MAKE_STRUCT_CASE      IterateStructBody(object_size, v);      break;    default:      PrintF("Unknown type: %d\n", type);      UNREACHABLE();  }}void HeapObject::IterateStructBody(int object_size, ObjectVisitor* v) {  IteratePointers(v, HeapObject::kHeaderSize, object_size);}Object* HeapNumber::HeapNumberToBoolean() {  // NaN, +0, and -0 should return the false object  switch (fpclassify(value())) {    case FP_NAN:  // fall through    case FP_ZERO: return Heap::false_value();    default: return Heap::true_value();  }}void HeapNumber::HeapNumberPrint() {  PrintF("%.16g", Number());}void HeapNumber::HeapNumberPrint(StringStream* accumulator) {  // The Windows version of vsnprintf can allocate when printing a %g string  // into a buffer that may not be big enough.  We don't want random memory  // allocation when producing post-crash stack traces, so we print into a  // buffer that is plenty big enough for any floating point number, then  // print that using vsnprintf (which may truncate but never allocate if  // there is no more space in the buffer).  EmbeddedVector<char, 100> buffer;  OS::SNPrintF(buffer, "%.16g", Number());  accumulator->Add("%s", buffer.start());}String* JSObject::class_name() {  if (IsJSFunction()) return Heap::function_class_symbol();  // If the constructor is not present "Object" is returned.  String* result = Heap::Object_symbol();  if (map()->constructor()->IsJSFunction()) {    JSFunction* constructor = JSFunction::cast(map()->constructor());    return String::cast(constructor->shared()->instance_class_name());  }  return result;}void JSObject::JSObjectIterateBody(int object_size, ObjectVisitor* v) {  // Iterate over all fields in the body. Assumes all are Object*.  IteratePointers(v, kPropertiesOffset, object_size);}Object* JSObject::Copy(PretenureFlag pretenure) {  // Never used to copy functions.  If functions need to be copied we  // have to be careful to clear the literals array.  ASSERT(!IsJSFunction());  // Copy the elements and properties.  Object* elem = FixedArray::cast(elements())->Copy();  if (elem->IsFailure()) return elem;  Object* prop = properties()->Copy();  if (prop->IsFailure()) return prop;  // Make the clone.  Object* clone = (pretenure == NOT_TENURED) ?      Heap::Allocate(map(), NEW_SPACE) :      Heap::Allocate(map(), OLD_POINTER_SPACE);  if (clone->IsFailure()) return clone;  JSObject::cast(clone)->CopyBody(this);  // Set the new elements and properties.  JSObject::cast(clone)->set_elements(FixedArray::cast(elem));  JSObject::cast(clone)->set_properties(FixedArray::cast(prop));  // Return the new clone.  return clone;}Object* JSObject::AddFastPropertyUsingMap(Map* new_map,                                          String* name,                                          Object* value) {  int index = new_map->PropertyIndexFor(name);  if (map()->unused_property_fields() > 0) {    ASSERT(index < properties()->length());    properties()->set(index, value);  } else {    ASSERT(map()->unused_property_fields() == 0);    int new_unused = new_map->unused_property_fields();    Object* values =        properties()->CopySize(properties()->length() + new_unused + 1);    if (values->IsFailure()) return values;    FixedArray::cast(values)->set(index, value);    set_properties(FixedArray::cast(values));  }  set_map(new_map);  return value;}Object* JSObject::AddFastProperty(String* name,                                  Object* value,                                  PropertyAttributes attributes) {  // Normalize the object if the name is not a real identifier.  StringInputBuffer buffer(name);  if (!Scanner::IsIdentifier(&buffer)) {    Object* obj = NormalizeProperties();    if (obj->IsFailure()) return obj;    return AddSlowProperty(name, value, attributes);  }  // Replace a CONSTANT_TRANSITION flag with a transition.  // Do this by removing it, and the standard code for adding a map transition  // will then run.  DescriptorArray* old_descriptors = map()->instance_descriptors();  int old_name_index = old_descriptors->Search(name);  bool constant_transition = false;  // Only used in assertions.  if (old_name_index != DescriptorArray::kNotFound && CONSTANT_TRANSITION ==      PropertyDetails(old_descriptors->GetDetails(old_name_index)).type()) {    constant_transition = true;    Object* r = old_descriptors->CopyRemove(name);    if (r->IsFailure()) return r;    old_descriptors = DescriptorArray::cast(r);    old_name_index = DescriptorArray::kNotFound;  }  // Compute the new index for new field.  int index = map()->NextFreePropertyIndex();  // Allocate new instance descriptors with (name, index) added  FieldDescriptor new_field(name, index, attributes);  Object* new_descriptors =      old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);  if (new_descriptors->IsFailure()) return new_descriptors;  // Only allow map transition if the object's map is NOT equal to the  // global object_function's map and there is not a transition for name.  bool allow_map_transition =        !old_descriptors->Contains(name) &&        (Top::context()->global_context()->object_function()->map() != map());  ASSERT(allow_map_transition || !constant_transition);  if (map()->unused_property_fields() > 0) {    ASSERT(index < properties()->length());    // Allocate a new map for the object.    Object* r = map()->Copy();    if (r->IsFailure()) return r;    Map* new_map = Map::cast(r);    if (allow_map_transition) {      // Allocate new instance descriptors for the old map with map transition.      MapTransitionDescriptor d(name, Map::cast(new_map), attributes);      Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);      if (r->IsFailure()) return r;      old_descriptors = DescriptorArray::cast(r);    }    // We have now allocated all the necessary objects.    // All the changes can be applied at once, so they are atomic.    map()->set_instance_descriptors(old_descriptors);    new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));    new_map->set_unused_property_fields(map()->unused_property_fields() - 1);    set_map(new_map);    properties()->set(index, value);  } else {    ASSERT(map()->unused_property_fields() == 0);    if (properties()->length() > kMaxFastProperties) {      Object* obj = NormalizeProperties();      if (obj->IsFailure()) return obj;      return AddSlowProperty(name, value, attributes);    }    static const int kExtraFields = 3;    // Make room for the new value    Object* values =        properties()->CopySize(properties()->length() + kExtraFields);    if (values->IsFailure()) return values;    FixedArray::cast(values)->set(index, value);    // Allocate a new map for the object.    Object* r = map()->Copy();    if (r->IsFailure()) return r;    Map* new_map = Map::cast(r);    if (allow_map_transition) {      MapTransitionDescriptor d(name, Map::cast(new_map), attributes);      // Allocate new instance descriptors for the old map with map transition.      Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);      if (r->IsFailure()) return r;      old_descriptors = DescriptorArray::cast(r);    }    // We have now allocated all the necessary objects.    // All changes can be done at once, atomically.    map()->set_instance_descriptors(old_descriptors);    new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));    new_map->set_unused_property_fields(kExtraFields - 1);    set_map(new_map);    set_properties(FixedArray::cast(values));  }  return value;}Object* JSObject::AddConstantFunctionProperty(String* name,                                              JSFunction* function,                                              PropertyAttributes attributes) {  // Allocate new instance descriptors with (name, function) added  ConstantFunctionDescriptor d(name, function, attributes);  Object* new_descriptors =      map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);  if (new_descriptors->IsFailure()) return new_descriptors;  // Allocate a new map for the object.  Object* new_map = map()->Copy();  if (new_map->IsFailure()) return new_map;  DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors);  Map::cast(new_map)->set_instance_descriptors(descriptors);  Map* old_map = map();  set_map(Map::cast(new_map));  // If the old map is the global object map (from new Object()),  // then transitions are not added to it, so we are done.  if (old_map == Top::context()->global_context()->object_function()->map()) {    return function;  }  // Do not add CONSTANT_TRANSITIONS to global objects  if (IsGlobalObject()) {    return function;  }  // Add a CONSTANT_TRANSITION descriptor to the old map,  // so future assignments to this property on other objects  // of the same type will create a normal field, not a constant function.  // Don't do this for special properties, with non-trival attributes.  if (attributes != NONE) {    return function;  }  ConstTransitionDescriptor mark(name);  new_descriptors =      old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS);  if (new_descriptors->IsFailure()) {    return function;  // We have accomplished the main goal, so return success.  }  old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));  return function;}Object* JSObject::ReplaceConstantFunctionProperty(String* name,                                                  Object* value) {  // There are two situations to handle here:  // 1: Replace a constant function with another function.  // 2: Replace a constant function with an object.  if (value->IsJSFunction()) {    JSFunction* function = JSFunction::cast(value);    Object* new_map = map()->CopyDropTransitions();    if (new_map->IsFailure()) return new_map;    set_map(Map::cast(new_map));    // Replace the function entry    int index = map()->instance_descriptors()->Search(name);    ASSERT(index != DescriptorArray::kNotFound);    map()->instance_descriptors()->ReplaceConstantFunction(index, function);  } else {    // Allocate new instance descriptors with updated property index.    int index = map()->NextFreePropertyIndex();    Object* new_descriptors =        map()->instance_descriptors()->CopyReplace(name, index, NONE);    if (new_descriptors->IsFailure()) return new_descriptors;    if (map()->unused_property_fields() > 0) {      ASSERT(index < properties()->length());      // Allocate a new map for the object.      Object* new_map = map()->Copy();      if (new_map->IsFailure()) return new_map;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -