Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Unified Diff: src/objects.cc

Issue 236843002: Revert "Track field types." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index dae7d51b6a1195117f87dcc108944324a1701cc7..aaa03203ae444987ec954edb1d4e19012e0791c5 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -73,23 +73,6 @@ MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
}
-Handle<HeapType> Object::OptimalType(Isolate* isolate,
- Representation representation) {
- if (!FLAG_track_field_types) return HeapType::Any(isolate);
- if (representation.IsNone()) return HeapType::None(isolate);
- if (representation.IsHeapObject() && IsHeapObject()) {
- // We can track only JavaScript objects with stable maps.
- Handle<Map> map(HeapObject::cast(this)->map(), isolate);
- if (map->is_stable() &&
- map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
- map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
- return HeapType::Class(map, isolate);
- }
- }
- return HeapType::Any(isolate);
-}
-
-
MaybeObject* Object::ToObject(Context* native_context) {
if (IsNumber()) {
return CreateJSValue(native_context->number_function(), this);
@@ -1464,9 +1447,7 @@ void Map::PrintGeneralization(FILE* file,
int descriptors,
bool constant_to_field,
Representation old_representation,
- Representation new_representation,
- HeapType* old_field_type,
- HeapType* new_field_type) {
+ Representation new_representation) {
PrintF(file, "[generalizing ");
constructor_name()->PrintOn(file);
PrintF(file, "] ");
@@ -1476,19 +1457,13 @@ void Map::PrintGeneralization(FILE* file,
} else {
PrintF(file, "{symbol %p}", static_cast<void*>(name));
}
- PrintF(file, ":");
if (constant_to_field) {
- PrintF(file, "c");
+ PrintF(file, ":c->f");
} else {
- PrintF(file, "%s", old_representation.Mnemonic());
- PrintF(file, "{");
- old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
- PrintF(file, "}");
- }
- PrintF(file, "->%s", new_representation.Mnemonic());
- PrintF(file, "{");
- new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
- PrintF(file, "}");
+ PrintF(file, ":%s->%s",
+ old_representation.Mnemonic(),
+ new_representation.Mnemonic());
+ }
PrintF(file, " (");
if (strlen(reason) > 0) {
PrintF(file, "%s", reason);
@@ -1880,12 +1855,10 @@ static Handle<Object> NewStorageFor(Isolate* isolate,
static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
Handle<Name> name,
int index,
- Handle<HeapType> field_type,
PropertyAttributes attributes,
Representation representation,
TransitionFlag flag) {
- FieldDescriptor new_field_desc(name, index, field_type,
- attributes, representation);
+ FieldDescriptor new_field_desc(name, index, attributes, representation);
Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
int unused_property_fields = map->unused_property_fields() - 1;
if (unused_property_fields < 0) {
@@ -1922,14 +1895,11 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
// Compute the new index for new field.
int index = object->map()->NextFreePropertyIndex();
- // Compute the optimal representation for the new field.
+ // Allocate new instance descriptors with (name, index) added
if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
Representation representation = value->OptimalRepresentation(value_type);
-
Handle<Map> new_map = CopyAddFieldDescriptor(
- handle(object->map()), name, index,
- value->OptimalType(isolate, representation),
- attributes, representation, flag);
+ handle(object->map()), name, index, attributes, representation, flag);
JSObject::MigrateToMap(object, new_map);
@@ -2375,11 +2345,9 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
int modify_index,
Representation new_representation,
- Handle<HeapType> new_field_type,
StoreMode store_mode) {
Handle<Map> new_map = Map::GeneralizeRepresentation(
- handle(object->map()), modify_index, new_representation,
- new_field_type, store_mode);
+ handle(object->map()), modify_index, new_representation, store_mode);
if (object->map() == *new_map) return;
return MigrateToMap(object, new_map);
}
@@ -2400,22 +2368,16 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
StoreMode store_mode,
PropertyAttributes attributes,
const char* reason) {
- Isolate* isolate = map->GetIsolate();
Handle<Map> new_map = Copy(map);
DescriptorArray* descriptors = new_map->instance_descriptors();
- int length = descriptors->number_of_descriptors();
- for (int i = 0; i < length; i++) {
- descriptors->SetRepresentation(i, Representation::Tagged());
- if (descriptors->GetDetails(i).type() == FIELD) {
- descriptors->SetValue(i, HeapType::Any());
- }
- }
+ descriptors->InitializeRepresentations(Representation::Tagged());
// Unless the instance is being migrated, ensure that modify_index is a field.
PropertyDetails details = descriptors->GetDetails(modify_index);
if (store_mode == FORCE_FIELD && details.type() != FIELD) {
- FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
+ FieldDescriptor d(handle(descriptors->GetKey(modify_index),
+ map->GetIsolate()),
new_map->NumberOfFields(),
attributes,
Representation::Tagged());
@@ -2428,15 +2390,11 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
}
if (FLAG_trace_generalization) {
- HeapType* field_type = (details.type() == FIELD)
- ? map->instance_descriptors()->GetFieldType(modify_index)
- : NULL;
map->PrintGeneralization(stdout, reason, modify_index,
new_map->NumberOfOwnDescriptors(),
new_map->NumberOfOwnDescriptors(),
details.type() == CONSTANT && store_mode == FORCE_FIELD,
- details.representation(), Representation::Tagged(),
- field_type, HeapType::Any());
+ Representation::Tagged(), Representation::Tagged());
}
return new_map;
}
@@ -2501,8 +2459,6 @@ Map* Map::FindRootMap() {
Map* Map::FindUpdatedMap(int verbatim,
int length,
DescriptorArray* descriptors) {
- DisallowHeapAllocation no_allocation;
-
// This can only be called on roots of transition trees.
ASSERT(GetBackPointer()->IsUndefined());
@@ -2537,8 +2493,6 @@ Map* Map::FindUpdatedMap(int verbatim,
Map* Map::FindLastMatchMap(int verbatim,
int length,
DescriptorArray* descriptors) {
- DisallowHeapAllocation no_allocation;
-
// This can only be called on roots of transition trees.
ASSERT(GetBackPointer()->IsUndefined());
@@ -2554,17 +2508,13 @@ Map* Map::FindLastMatchMap(int verbatim,
Map* next = transitions->GetTarget(transition);
DescriptorArray* next_descriptors = next->instance_descriptors();
+ if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break;
+
PropertyDetails details = descriptors->GetDetails(i);
PropertyDetails next_details = next_descriptors->GetDetails(i);
if (details.type() != next_details.type()) break;
if (details.attributes() != next_details.attributes()) break;
if (!details.representation().Equals(next_details.representation())) break;
- if (next_details.type() == FIELD) {
- if (!descriptors->GetFieldType(i)->NowIs(
- next_descriptors->GetFieldType(i))) break;
- } else {
- if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
- }
current = next;
}
@@ -2572,87 +2522,6 @@ Map* Map::FindLastMatchMap(int verbatim,
}
-Map* Map::FindFieldOwner(int descriptor) {
- DisallowHeapAllocation no_allocation;
- ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type());
- Map* result = this;
- while (true) {
- Object* back = result->GetBackPointer();
- if (back->IsUndefined()) break;
- Map* parent = Map::cast(back);
- if (parent->NumberOfOwnDescriptors() <= descriptor) break;
- result = parent;
- }
- return result;
-}
-
-
-void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) {
- DisallowHeapAllocation no_allocation;
- if (HasTransitionArray()) {
- TransitionArray* transitions = this->transitions();
- for (int i = 0; i < transitions->number_of_transitions(); ++i) {
- transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc);
- }
- }
- instance_descriptors()->Replace(descriptor_number, desc);;
-}
-
-
-// static
-Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> old_field_type,
- Handle<HeapType> new_field_type,
- Isolate* isolate) {
- if (new_field_type->NowIs(old_field_type)) return old_field_type;
- if (old_field_type->NowIs(new_field_type)) return new_field_type;
- return HeapType::Any(isolate);
-}
-
-
-// static
-void Map::GeneralizeFieldType(Handle<Map> map,
- int modify_index,
- Handle<HeapType> new_field_type) {
- Isolate* isolate = map->GetIsolate();
- Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
- Handle<DescriptorArray> descriptors(
- field_owner->instance_descriptors(), isolate);
-
- // Check if we actually need to generalize the field type at all.
- Handle<HeapType> old_field_type(
- descriptors->GetFieldType(modify_index), isolate);
- if (new_field_type->NowIs(old_field_type)) {
- ASSERT(Map::GeneralizeFieldType(old_field_type,
- new_field_type,
- isolate)->NowIs(old_field_type));
- return;
- }
-
- // Determine the generalized new field type.
- new_field_type = Map::GeneralizeFieldType(
- old_field_type, new_field_type, isolate);
-
- PropertyDetails details = descriptors->GetDetails(modify_index);
- FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
- descriptors->GetFieldIndex(modify_index),
- new_field_type,
- details.attributes(),
- details.representation());
- field_owner->UpdateDescriptor(modify_index, &d);
- field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
- isolate, DependentCode::kFieldTypeGroup);
-
- if (FLAG_trace_generalization) {
- map->PrintGeneralization(
- stdout, "field type generalization",
- modify_index, map->NumberOfOwnDescriptors(),
- map->NumberOfOwnDescriptors(), false,
- details.representation(), details.representation(),
- *old_field_type, *new_field_type);
- }
-}
-
-
// Generalize the representation of the descriptor at |modify_index|.
// This method rewrites the transition tree to reflect the new change. To avoid
// high degrees over polymorphism, and to stabilize quickly, on every rewrite
@@ -2674,7 +2543,6 @@ void Map::GeneralizeFieldType(Handle<Map> map,
Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
int modify_index,
Representation new_representation,
- Handle<HeapType> new_field_type,
StoreMode store_mode) {
Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
@@ -2687,28 +2555,11 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
if (old_representation.IsNone() &&
!new_representation.IsNone() &&
!new_representation.IsDouble()) {
- ASSERT(old_details.type() == FIELD);
- ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs(
- HeapType::None()));
- if (FLAG_trace_generalization) {
- old_map->PrintGeneralization(
- stdout, "uninitialized field",
- modify_index, old_map->NumberOfOwnDescriptors(),
- old_map->NumberOfOwnDescriptors(), false,
- old_representation, new_representation,
- old_descriptors->GetFieldType(modify_index), *new_field_type);
- }
old_descriptors->SetRepresentation(modify_index, new_representation);
- old_descriptors->SetValue(modify_index, *new_field_type);
- return old_map;
- }
-
- if (new_representation.Equals(old_representation) &&
- old_details.type() == FIELD) {
- Map::GeneralizeFieldType(old_map, modify_index, new_field_type);
return old_map;
}
+ int descriptors = old_map->NumberOfOwnDescriptors();
Handle<Map> root_map(old_map->FindRootMap());
// Check the state of the root map.
@@ -2724,7 +2575,6 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
old_details.attributes(), "root modification");
}
- int descriptors = old_map->NumberOfOwnDescriptors();
Map* raw_updated = root_map->FindUpdatedMap(
verbatim, descriptors, *old_descriptors);
if (raw_updated == NULL) {
@@ -2754,7 +2604,6 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
ASSERT(store_mode == ALLOW_AS_CONSTANT ||
new_descriptors->GetDetails(modify_index).type() == FIELD);
- Isolate* isolate = new_descriptors->GetIsolate();
old_representation =
new_descriptors->GetDetails(modify_index).representation();
Representation updated_representation =
@@ -2762,13 +2611,6 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
if (!updated_representation.Equals(old_representation)) {
new_descriptors->SetRepresentation(modify_index, updated_representation);
}
- if (new_descriptors->GetDetails(modify_index).type() == FIELD) {
- Handle<HeapType> field_type(
- new_descriptors->GetFieldType(modify_index), isolate);
- new_field_type = Map::GeneralizeFieldType(
- field_type, new_field_type, isolate);
- new_descriptors->SetValue(modify_index, *new_field_type);
- }
Handle<Map> split_map(root_map->FindLastMatchMap(
verbatim, descriptors, *new_descriptors));
@@ -2783,21 +2625,11 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
old_descriptors->GetKey(descriptor), *new_descriptors);
if (FLAG_trace_generalization) {
- PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
- PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
- Handle<HeapType> old_field_type = (old_details.type() == FIELD)
- ? handle(old_descriptors->GetFieldType(modify_index), isolate)
- : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
- isolate), isolate);
- Handle<HeapType> new_field_type = (new_details.type() == FIELD)
- ? handle(new_descriptors->GetFieldType(modify_index), isolate)
- : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
- isolate), isolate);
old_map->PrintGeneralization(
stdout, "", modify_index, descriptor, descriptors,
- old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
- old_details.representation(), new_details.representation(),
- *old_field_type, *new_field_type);
+ old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
+ store_mode == FORCE_FIELD,
+ old_representation, updated_representation);
}
// Add missing transitions.
@@ -2813,13 +2645,13 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
// Generalize the representation of all FIELD descriptors.
Handle<Map> Map::GeneralizeAllFieldRepresentations(
- Handle<Map> map) {
+ Handle<Map> map,
+ Representation new_representation) {
Handle<DescriptorArray> descriptors(map->instance_descriptors());
- for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
- if (descriptors->GetDetails(i).type() == FIELD) {
- map = GeneralizeRepresentation(map, i, Representation::Tagged(),
- HeapType::Any(map->GetIsolate()),
- FORCE_FIELD);
+ for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
+ PropertyDetails details = descriptors->GetDetails(i);
+ if (details.type() == FIELD) {
+ map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
}
}
return map;
@@ -3958,9 +3790,7 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
// transition that matches the object. This achieves what is needed.
Handle<Map> original_map(object->map());
GeneralizeFieldRepresentation(
- object, 0, Representation::None(),
- HeapType::None(object->GetIsolate()),
- ALLOW_AS_CONSTANT);
+ object, 0, Representation::None(), ALLOW_AS_CONSTANT);
object->map()->set_migration_target(true);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, object->map());
@@ -3989,7 +3819,7 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
Handle<Map> transition_map(lookup->GetTransitionTarget());
int descriptor = transition_map->LastAdded();
- Handle<DescriptorArray> descriptors(transition_map->instance_descriptors());
+ DescriptorArray* descriptors = transition_map->instance_descriptors();
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.type() == CALLBACKS || attributes != details.attributes()) {
@@ -4006,19 +3836,17 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
// Keep the target CONSTANT if the same value is stored.
// TODO(verwaest): Also support keeping the placeholder
// (value->IsUninitialized) as constant.
- if (!lookup->CanHoldValue(value)) {
- Representation field_representation = value->OptimalRepresentation();
- Handle<HeapType> field_type = value->OptimalType(
- lookup->isolate(), field_representation);
- transition_map = Map::GeneralizeRepresentation(
- transition_map, descriptor,
- field_representation, field_type, FORCE_FIELD);
+ if (!lookup->CanHoldValue(value) ||
+ (details.type() == CONSTANT &&
+ descriptors->GetValue(descriptor) != *value)) {
+ transition_map = Map::GeneralizeRepresentation(transition_map,
+ descriptor, value->OptimalRepresentation(), FORCE_FIELD);
}
JSObject::MigrateToMap(object, transition_map);
// Reload.
- descriptors = handle(transition_map->instance_descriptors());
+ descriptors = transition_map->instance_descriptors();
details = descriptors->GetDetails(descriptor);
if (details.type() != FIELD) return value;
@@ -4040,13 +3868,11 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
static void SetPropertyToField(LookupResult* lookup,
Handle<Object> value) {
Representation representation = lookup->representation();
- if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) {
- Representation field_representation = value->OptimalRepresentation();
- Handle<HeapType> field_type = value->OptimalType(
- lookup->isolate(), field_representation);
+ if (!lookup->CanHoldValue(value) ||
+ lookup->type() == CONSTANT) {
JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
lookup->GetDescriptorIndex(),
- field_representation, field_type,
+ value->OptimalRepresentation(),
FORCE_FIELD);
DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
int descriptor = lookup->GetDescriptorIndex();
@@ -4082,8 +3908,7 @@ static void ConvertAndSetLocalProperty(LookupResult* lookup,
int descriptor_index = lookup->GetDescriptorIndex();
if (lookup->GetAttributes() == attributes) {
JSObject::GeneralizeFieldRepresentation(
- object, descriptor_index, Representation::Tagged(),
- HeapType::Any(lookup->isolate()), FORCE_FIELD);
+ object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
} else {
Handle<Map> old_map(object->map());
Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
@@ -7071,13 +6896,7 @@ Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
map->set_transitions(*transitions);
result->SetBackPointer(*map);
} else {
- int length = descriptors->number_of_descriptors();
- for (int i = 0; i < length; i++) {
- descriptors->SetRepresentation(i, Representation::Tagged());
- if (descriptors->GetDetails(i).type() == FIELD) {
- descriptors->SetValue(i, HeapType::Any());
- }
- }
+ descriptors->InitializeRepresentations(Representation::Tagged());
}
return result;
@@ -8266,27 +8085,16 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
(left_details.type() == CONSTANT &&
right_details.type() == CONSTANT &&
left->GetValue(descriptor) != right->GetValue(descriptor))) {
- ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD);
- ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD);
Representation representation = left_details.representation().generalize(
right_details.representation());
- Handle<HeapType> left_type = (left_details.type() == FIELD)
- ? handle(left->GetFieldType(descriptor), isolate)
- : left->GetValue(descriptor)->OptimalType(isolate, representation);
- Handle<HeapType> right_type = (right_details.type() == FIELD)
- ? handle(right->GetFieldType(descriptor), isolate)
- : right->GetValue(descriptor)->OptimalType(isolate, representation);
- Handle<HeapType> field_type = Map::GeneralizeFieldType(
- left_type, right_type, isolate);
- FieldDescriptor d(handle(left->GetKey(descriptor), isolate),
+ FieldDescriptor d(handle(left->GetKey(descriptor)),
current_offset++,
- field_type,
right_details.attributes(),
representation);
result->Set(descriptor, &d);
} else {
- Descriptor d(handle(right->GetKey(descriptor), isolate),
- handle(right->GetValue(descriptor), isolate),
+ Descriptor d(handle(right->GetKey(descriptor)),
+ handle(right->GetValue(descriptor), right->GetIsolate()),
right_details);
result->Set(descriptor, &d);
}
@@ -8295,27 +8103,16 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
// |valid| -> |new_size|
for (; descriptor < new_size; descriptor++) {
PropertyDetails right_details = right->GetDetails(descriptor);
- if (right_details.type() == FIELD) {
- FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
+ if (right_details.type() == FIELD ||
+ (store_mode == FORCE_FIELD && descriptor == modify_index)) {
+ FieldDescriptor d(handle(right->GetKey(descriptor)),
current_offset++,
- handle(right->GetFieldType(descriptor), isolate),
right_details.attributes(),
right_details.representation());
result->Set(descriptor, &d);
- } else if (store_mode == FORCE_FIELD && descriptor == modify_index) {
- ASSERT_EQ(CONSTANT, right_details.type());
- Representation field_representation = right_details.representation();
- Handle<HeapType> field_type = right->GetValue(descriptor)->OptimalType(
- isolate, field_representation);
- FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
- current_offset++,
- field_type,
- right_details.attributes(),
- field_representation);
- result->Set(descriptor, &d);
} else {
- Descriptor d(handle(right->GetKey(descriptor), isolate),
- handle(right->GetValue(descriptor), isolate),
+ Descriptor d(handle(right->GetKey(descriptor)),
+ handle(right->GetValue(descriptor), right->GetIsolate()),
right_details);
result->Set(descriptor, &d);
}
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698