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

Unified Diff: src/api.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 10 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/api.h ('k') | src/arm/OWNERS » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 27c4c627ea703914b17821711ac0660193af2258..2c7db3be1656f10d475dd8e1de71a89ed374cdd6 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1578,7 +1578,14 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
i::Handle<i::String> str = Utils::OpenHandle(*source);
i::Isolate* isolate = str->GetIsolate();
- return i::PreParserApi::PreParse(isolate, str);
+ if (str->IsExternalTwoByteString()) {
+ i::ExternalTwoByteStringUtf16CharacterStream stream(
+ i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
+ return i::PreParserApi::PreParse(isolate, &stream);
+ } else {
+ i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
+ return i::PreParserApi::PreParse(isolate, &stream);
+ }
}
@@ -2364,26 +2371,14 @@ bool Value::IsTypedArray() const {
}
-#define TYPED_ARRAY_LIST(F) \
- F(Uint8Array, kExternalUnsignedByteArray) \
- F(Int8Array, kExternalByteArray) \
- F(Uint16Array, kExternalUnsignedShortArray) \
- F(Int16Array, kExternalShortArray) \
- F(Uint32Array, kExternalUnsignedIntArray) \
- F(Int32Array, kExternalIntArray) \
- F(Float32Array, kExternalFloatArray) \
- F(Float64Array, kExternalDoubleArray) \
- F(Uint8ClampedArray, kExternalPixelArray)
-
-
-#define VALUE_IS_TYPED_ARRAY(TypedArray, type_const) \
- bool Value::Is##TypedArray() const { \
- i::Handle<i::Object> obj = Utils::OpenHandle(this); \
- if (!obj->IsJSTypedArray()) return false; \
- return i::JSTypedArray::cast(*obj)->type() == type_const; \
+#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
+ bool Value::Is##Type##Array() const { \
+ i::Handle<i::Object> obj = Utils::OpenHandle(this); \
+ return obj->IsJSTypedArray() && \
+ i::JSTypedArray::cast(*obj)->type() == kExternal##Type##Array; \
}
-TYPED_ARRAY_LIST(VALUE_IS_TYPED_ARRAY)
+TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
#undef VALUE_IS_TYPED_ARRAY
@@ -2715,17 +2710,18 @@ void v8::TypedArray::CheckCast(Value* that) {
}
-#define CHECK_TYPED_ARRAY_CAST(ApiClass, typeConst) \
- void v8::ApiClass::CheckCast(Value* that) { \
- i::Handle<i::Object> obj = Utils::OpenHandle(that); \
- Utils::ApiCheck(obj->IsJSTypedArray() && \
- i::JSTypedArray::cast(*obj)->type() == typeConst, \
- "v8::" #ApiClass "::Cast()", \
- "Could not convert to " #ApiClass); \
+#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
+ void v8::Type##Array::CheckCast(Value* that) { \
+ i::Handle<i::Object> obj = Utils::OpenHandle(that); \
+ Utils::ApiCheck(obj->IsJSTypedArray() && \
+ i::JSTypedArray::cast(*obj)->type() == \
+ kExternal##Type##Array, \
+ "v8::" #Type "Array::Cast()", \
+ "Could not convert to " #Type "Array"); \
}
-TYPED_ARRAY_LIST(CHECK_TYPED_ARRAY_CAST)
+TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
#undef CHECK_TYPED_ARRAY_CAST
@@ -3658,33 +3654,12 @@ namespace {
static i::ElementsKind GetElementsKindFromExternalArrayType(
ExternalArrayType array_type) {
switch (array_type) {
- case kExternalByteArray:
- return i::EXTERNAL_BYTE_ELEMENTS;
- break;
- case kExternalUnsignedByteArray:
- return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
- break;
- case kExternalShortArray:
- return i::EXTERNAL_SHORT_ELEMENTS;
- break;
- case kExternalUnsignedShortArray:
- return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
- break;
- case kExternalIntArray:
- return i::EXTERNAL_INT_ELEMENTS;
- break;
- case kExternalUnsignedIntArray:
- return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
- break;
- case kExternalFloatArray:
- return i::EXTERNAL_FLOAT_ELEMENTS;
- break;
- case kExternalDoubleArray:
- return i::EXTERNAL_DOUBLE_ELEMENTS;
- break;
- case kExternalPixelArray:
- return i::EXTERNAL_PIXEL_ELEMENTS;
- break;
+#define ARRAY_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
+ case kExternal##Type##Array: \
+ return i::EXTERNAL_##TYPE##_ELEMENTS;
+
+ TYPED_ARRAYS(ARRAY_TYPE_TO_ELEMENTS_KIND)
+#undef ARRAY_TYPE_TO_ELEMENTS_KIND
}
UNREACHABLE();
return i::DICTIONARY_ELEMENTS;
@@ -3717,7 +3692,7 @@ void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
if (!Utils::ApiCheck(length >= 0 &&
- length <= i::ExternalPixelArray::kMaxLength,
+ length <= i::ExternalUint8ClampedArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToPixelData()",
"length exceeds max acceptable value")) {
return;
@@ -3728,7 +3703,7 @@ void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
"JSArray is not supported")) {
return;
}
- PrepareExternalArrayElements(self, data, kExternalPixelArray, length);
+ PrepareExternalArrayElements(self, data, kExternalUint8ClampedArray, length);
}
@@ -3736,7 +3711,7 @@ bool v8::Object::HasIndexedPropertiesInPixelData() {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
return false);
- return self->HasExternalPixelElements();
+ return self->HasExternalUint8ClampedElements();
}
@@ -3744,9 +3719,9 @@ uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
return NULL);
- if (self->HasExternalPixelElements()) {
- return i::ExternalPixelArray::cast(self->elements())->
- external_pixel_pointer();
+ if (self->HasExternalUint8ClampedElements()) {
+ return i::ExternalUint8ClampedArray::cast(self->elements())->
+ external_uint8_clamped_pointer();
} else {
return NULL;
}
@@ -3757,8 +3732,8 @@ int v8::Object::GetIndexedPropertiesPixelDataLength() {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
return -1);
- if (self->HasExternalPixelElements()) {
- return i::ExternalPixelArray::cast(self->elements())->length();
+ if (self->HasExternalUint8ClampedElements()) {
+ return i::ExternalUint8ClampedArray::cast(self->elements())->length();
} else {
return -1;
}
@@ -3816,24 +3791,11 @@ ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
"v8::GetIndexedPropertiesExternalArrayDataType()",
return static_cast<ExternalArrayType>(-1));
switch (self->elements()->map()->instance_type()) {
- case i::EXTERNAL_BYTE_ARRAY_TYPE:
- return kExternalByteArray;
- case i::EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
- return kExternalUnsignedByteArray;
- case i::EXTERNAL_SHORT_ARRAY_TYPE:
- return kExternalShortArray;
- case i::EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
- return kExternalUnsignedShortArray;
- case i::EXTERNAL_INT_ARRAY_TYPE:
- return kExternalIntArray;
- case i::EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
- return kExternalUnsignedIntArray;
- case i::EXTERNAL_FLOAT_ARRAY_TYPE:
- return kExternalFloatArray;
- case i::EXTERNAL_DOUBLE_ARRAY_TYPE:
- return kExternalDoubleArray;
- case i::EXTERNAL_PIXEL_ARRAY_TYPE:
- return kExternalPixelArray;
+#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \
+ case i::EXTERNAL_##TYPE##_ARRAY_TYPE: \
+ return kExternal##Type##Array;
+ TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
+#undef INSTANCE_TYPE_TO_ARRAY_TYPE
default:
return static_cast<ExternalArrayType>(-1);
}
@@ -4447,28 +4409,35 @@ int String::Utf8Length() const {
class Utf8WriterVisitor {
public:
Utf8WriterVisitor(
- char* buffer, int capacity, bool skip_capacity_check)
- : early_termination_(false),
- last_character_(unibrow::Utf16::kNoPreviousCharacter),
- buffer_(buffer),
- start_(buffer),
- capacity_(capacity),
- skip_capacity_check_(capacity == -1 || skip_capacity_check),
- utf16_chars_read_(0) {
+ char* buffer,
+ int capacity,
+ bool skip_capacity_check,
+ bool replace_invalid_utf8)
+ : early_termination_(false),
+ last_character_(unibrow::Utf16::kNoPreviousCharacter),
+ buffer_(buffer),
+ start_(buffer),
+ capacity_(capacity),
+ skip_capacity_check_(capacity == -1 || skip_capacity_check),
+ replace_invalid_utf8_(replace_invalid_utf8),
+ utf16_chars_read_(0) {
}
static int WriteEndCharacter(uint16_t character,
int last_character,
int remaining,
- char* const buffer) {
+ char* const buffer,
+ bool replace_invalid_utf8) {
using namespace unibrow;
ASSERT(remaining > 0);
// We can't use a local buffer here because Encode needs to modify
// previous characters in the stream. We know, however, that
// exactly one character will be advanced.
- if (Utf16::IsTrailSurrogate(character) &&
- Utf16::IsLeadSurrogate(last_character)) {
- int written = Utf8::Encode(buffer, character, last_character);
+ if (Utf16::IsSurrogatePair(last_character, character)) {
+ int written = Utf8::Encode(buffer,
+ character,
+ last_character,
+ replace_invalid_utf8);
ASSERT(written == 1);
return written;
}
@@ -4477,7 +4446,8 @@ class Utf8WriterVisitor {
// Can't encode using last_character as gcc has array bounds issues.
int written = Utf8::Encode(temp_buffer,
character,
- Utf16::kNoPreviousCharacter);
+ Utf16::kNoPreviousCharacter,
+ replace_invalid_utf8);
// Won't fit.
if (written > remaining) return 0;
// Copy over the character from temp_buffer.
@@ -4487,6 +4457,16 @@ class Utf8WriterVisitor {
return written;
}
+ // Visit writes out a group of code units (chars) of a v8::String to the
+ // internal buffer_. This is done in two phases. The first phase calculates a
+ // pesimistic estimate (writable_length) on how many code units can be safely
+ // written without exceeding the buffer capacity and without writing the last
+ // code unit (it could be a lead surrogate). The estimated number of code
+ // units is then written out in one go, and the reported byte usage is used
+ // to correct the estimate. This is repeated until the estimate becomes <= 0
+ // or all code units have been written out. The second phase writes out code
+ // units until the buffer capacity is reached, would be exceeded by the next
+ // unit, or all units have been written out.
template<typename Char>
void Visit(const Char* chars, const int length) {
using namespace unibrow;
@@ -4524,7 +4504,10 @@ class Utf8WriterVisitor {
} else {
for (; i < fast_length; i++) {
uint16_t character = *chars++;
- buffer += Utf8::Encode(buffer, character, last_character);
+ buffer += Utf8::Encode(buffer,
+ character,
+ last_character,
+ replace_invalid_utf8_);
last_character = character;
ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
}
@@ -4544,10 +4527,17 @@ class Utf8WriterVisitor {
ASSERT(remaining_capacity >= 0);
for (; i < length && remaining_capacity > 0; i++) {
uint16_t character = *chars++;
+ // remaining_capacity is <= 3 bytes at this point, so we do not write out
+ // an umatched lead surrogate.
+ if (replace_invalid_utf8_ && Utf16::IsLeadSurrogate(character)) {
+ early_termination_ = true;
+ break;
+ }
int written = WriteEndCharacter(character,
last_character,
remaining_capacity,
- buffer);
+ buffer,
+ replace_invalid_utf8_);
if (written == 0) {
early_termination_ = true;
break;
@@ -4595,6 +4585,7 @@ class Utf8WriterVisitor {
char* const start_;
int capacity_;
bool const skip_capacity_check_;
+ bool const replace_invalid_utf8_;
int utf16_chars_read_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
};
@@ -4633,9 +4624,11 @@ int String::WriteUtf8(char* buffer,
}
const int string_length = str->length();
bool write_null = !(options & NO_NULL_TERMINATION);
+ bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
+ int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
// First check if we can just write the string without checking capacity.
- if (capacity == -1 || capacity / 3 >= string_length) {
- Utf8WriterVisitor writer(buffer, capacity, true);
+ if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
+ Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
const int kMaxRecursion = 100;
bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
if (success) return writer.CompleteWrite(write_null, nchars_ref);
@@ -4663,7 +4656,7 @@ int String::WriteUtf8(char* buffer,
}
// Recursive slow path can potentially be unreasonable slow. Flatten.
str = FlattenGetString(str);
- Utf8WriterVisitor writer(buffer, capacity, false);
+ Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
i::String::VisitFlat(&writer, *str);
return writer.CompleteWrite(write_null, nchars_ref);
}
@@ -5433,23 +5426,6 @@ static i::Handle<i::String> NewExternalAsciiStringHandle(
}
-static bool RedirectToExternalString(i::Isolate* isolate,
- i::Handle<i::String> parent,
- i::Handle<i::String> external) {
- if (parent->IsConsString()) {
- i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent);
- cons->set_first(*external);
- cons->set_second(isolate->heap()->empty_string());
- } else {
- ASSERT(parent->IsSlicedString());
- i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent);
- slice->set_parent(*external);
- slice->set_offset(0);
- }
- return true;
-}
-
-
Local<String> v8::String::NewExternal(
Isolate* isolate,
v8::String::ExternalStringResource* resource) {
@@ -5479,22 +5455,10 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
}
CHECK(resource && resource->data());
- bool result;
- i::Handle<i::String> external;
- if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
- // We do not allow external strings in the old pointer space. Instead of
- // converting the string in-place, we keep the cons/sliced string and
- // point it to a newly-allocated external string.
- external = NewExternalStringHandle(isolate, resource);
- result = RedirectToExternalString(isolate, obj, external);
- } else {
- result = obj->MakeExternal(resource);
- external = obj;
- }
-
+ bool result = obj->MakeExternal(resource);
if (result) {
- ASSERT(external->IsExternalString());
- isolate->heap()->external_string_table()->AddString(*external);
+ ASSERT(obj->IsExternalString());
+ isolate->heap()->external_string_table()->AddString(*obj);
}
return result;
}
@@ -5531,22 +5495,10 @@ bool v8::String::MakeExternal(
}
CHECK(resource && resource->data());
- bool result;
- i::Handle<i::String> external;
- if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
- // We do not allow external strings in the old pointer space. Instead of
- // converting the string in-place, we keep the cons/sliced string and
- // point it to a newly-allocated external string.
- external = NewExternalAsciiStringHandle(isolate, resource);
- result = RedirectToExternalString(isolate, obj, external);
- } else {
- result = obj->MakeExternal(resource);
- external = obj;
- }
-
+ bool result = obj->MakeExternal(resource);
if (result) {
- ASSERT(external->IsExternalString());
- isolate->heap()->external_string_table()->AddString(*external);
+ ASSERT(obj->IsExternalString());
+ isolate->heap()->external_string_table()->AddString(*obj);
}
return result;
}
@@ -5980,41 +5932,24 @@ i::Handle<i::JSTypedArray> NewTypedArray(
}
-#define TYPED_ARRAY_NEW(TypedArray, element_type, array_type, elements_kind) \
- Local<TypedArray> TypedArray::New(Handle<ArrayBuffer> array_buffer, \
+#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
+ Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
size_t byte_offset, size_t length) { \
i::Isolate* isolate = i::Isolate::Current(); \
EnsureInitializedForIsolate(isolate, \
- "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
+ "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
LOG_API(isolate, \
- "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \
+ "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
ENTER_V8(isolate); \
i::Handle<i::JSTypedArray> obj = \
- NewTypedArray<element_type, array_type, elements_kind>( \
+ NewTypedArray<ctype, v8::kExternal##Type##Array, \
+ i::EXTERNAL_##TYPE##_ELEMENTS>( \
isolate, array_buffer, byte_offset, length); \
- return Utils::ToLocal##TypedArray(obj); \
- }
-
-
-TYPED_ARRAY_NEW(Uint8Array, uint8_t, kExternalUnsignedByteArray,
- i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS)
-TYPED_ARRAY_NEW(Uint8ClampedArray, uint8_t, kExternalPixelArray,
- i::EXTERNAL_PIXEL_ELEMENTS)
-TYPED_ARRAY_NEW(Int8Array, int8_t, kExternalByteArray,
- i::EXTERNAL_BYTE_ELEMENTS)
-TYPED_ARRAY_NEW(Uint16Array, uint16_t, kExternalUnsignedShortArray,
- i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS)
-TYPED_ARRAY_NEW(Int16Array, int16_t, kExternalShortArray,
- i::EXTERNAL_SHORT_ELEMENTS)
-TYPED_ARRAY_NEW(Uint32Array, uint32_t, kExternalUnsignedIntArray,
- i::EXTERNAL_UNSIGNED_INT_ELEMENTS)
-TYPED_ARRAY_NEW(Int32Array, int32_t, kExternalIntArray,
- i::EXTERNAL_INT_ELEMENTS)
-TYPED_ARRAY_NEW(Float32Array, float, kExternalFloatArray,
- i::EXTERNAL_FLOAT_ELEMENTS)
-TYPED_ARRAY_NEW(Float64Array, double, kExternalDoubleArray,
- i::EXTERNAL_DOUBLE_ELEMENTS)
+ return Utils::ToLocal##Type##Array(obj); \
+ }
+
+TYPED_ARRAYS(TYPED_ARRAY_NEW)
#undef TYPED_ARRAY_NEW
Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
@@ -6358,6 +6293,25 @@ void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
}
+void V8::RunMicrotasks(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::HandleScope scope(i_isolate);
+ i::V8::RunMicrotasks(i_isolate);
+}
+
+
+void V8::EnqueueMicrotask(Isolate* isolate, Handle<Function> microtask) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ i::Execution::EnqueueMicrotask(i_isolate, Utils::OpenHandle(*microtask));
+}
+
+
+void V8::SetAutorunMicrotasks(Isolate* isolate, bool autorun) {
+ reinterpret_cast<i::Isolate*>(isolate)->set_autorun_microtasks(autorun);
+}
+
+
void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
i::V8::RemoveCallCompletedCallback(callback);
}
@@ -6406,8 +6360,8 @@ void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
} else {
ASSERT_EQ(kFullGarbageCollection, type);
reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
- i::Heap::kNoGCFlags, "Isolate::RequestGarbageCollection",
- kGCCallbackFlagForced);
+ i::Heap::kAbortIncrementalMarkingMask,
+ "Isolate::RequestGarbageCollection", kGCCallbackFlagForced);
}
}
@@ -6968,11 +6922,11 @@ Handle<Value> HeapGraphEdge::GetName() const {
case i::HeapGraphEdge::kInternal:
case i::HeapGraphEdge::kProperty:
case i::HeapGraphEdge::kShortcut:
+ case i::HeapGraphEdge::kWeak:
return ToApiHandle<String>(
isolate->factory()->InternalizeUtf8String(edge->name()));
case i::HeapGraphEdge::kElement:
case i::HeapGraphEdge::kHidden:
- case i::HeapGraphEdge::kWeak:
return ToApiHandle<Number>(
isolate->factory()->NewNumberFromInt(edge->index()));
default: UNREACHABLE();
@@ -7017,6 +6971,13 @@ SnapshotObjectId HeapGraphNode::GetId() const {
int HeapGraphNode::GetSelfSize() const {
+ size_t size = ToInternal(this)->self_size();
+ CHECK(size <= static_cast<size_t>(internal::kMaxInt));
+ return static_cast<int>(size);
+}
+
+
+size_t HeapGraphNode::GetShallowSize() const {
return ToInternal(this)->self_size();
}
« no previous file with comments | « src/api.h ('k') | src/arm/OWNERS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698