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

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 506683003: Use isolate parameter while creating handles during class finalizers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 // conflict with an accessible static setter 'v=' of a super class). 1265 // conflict with an accessible static setter 'v=' of a super class).
1266 // The compile-time errors we report are: 1266 // The compile-time errors we report are:
1267 // - a static member 'v' conflicting with an inherited instance member 'v'. 1267 // - a static member 'v' conflicting with an inherited instance member 'v'.
1268 // - a static setter 'v=' conflicting with an inherited instance setter 'v='. 1268 // - a static setter 'v=' conflicting with an inherited instance setter 'v='.
1269 // - an instance method conflicting with an inherited instance field or 1269 // - an instance method conflicting with an inherited instance field or
1270 // instance getter. 1270 // instance getter.
1271 // - an instance field or instance getter conflicting with an inherited 1271 // - an instance field or instance getter conflicting with an inherited
1272 // instance method. 1272 // instance method.
1273 1273
1274 // Resolve type of fields and check for conflicts in super classes. 1274 // Resolve type of fields and check for conflicts in super classes.
1275 Array& array = Array::Handle(cls.fields()); 1275 Isolate* I = Isolate::Current();
1276 Field& field = Field::Handle(); 1276 Array& array = Array::Handle(I, cls.fields());
1277 AbstractType& type = AbstractType::Handle(); 1277 Field& field = Field::Handle(I);
1278 String& name = String::Handle(); 1278 AbstractType& type = AbstractType::Handle(I);
1279 String& getter_name = String::Handle(); 1279 String& name = String::Handle(I);
1280 String& setter_name = String::Handle(); 1280 String& getter_name = String::Handle(I);
1281 Class& super_class = Class::Handle(); 1281 String& setter_name = String::Handle(I);
1282 Class& super_class = Class::Handle(I);
1282 const intptr_t num_fields = array.Length(); 1283 const intptr_t num_fields = array.Length();
1283 for (intptr_t i = 0; i < num_fields; i++) { 1284 for (intptr_t i = 0; i < num_fields; i++) {
1284 field ^= array.At(i); 1285 field ^= array.At(i);
1285 type = field.type(); 1286 type = field.type();
1286 type = FinalizeType(cls, type, kCanonicalize); 1287 type = FinalizeType(cls, type, kCanonicalize);
1287 field.set_type(type); 1288 field.set_type(type);
1288 name = field.name(); 1289 name = field.name();
1289 if (field.is_static()) { 1290 if (field.is_static()) {
1290 getter_name = Field::GetterSymbol(name); 1291 getter_name = Field::GetterSymbol(name);
1291 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); 1292 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name);
1292 if (!super_class.IsNull()) { 1293 if (!super_class.IsNull()) {
1293 const String& class_name = String::Handle(cls.Name()); 1294 const String& class_name = String::Handle(I, cls.Name());
1294 const String& super_class_name = String::Handle(super_class.Name()); 1295 const String& super_class_name = String::Handle(I, super_class.Name());
1295 ReportError(cls, field.token_pos(), 1296 ReportError(cls, field.token_pos(),
1296 "static field '%s' of class '%s' conflicts with " 1297 "static field '%s' of class '%s' conflicts with "
1297 "instance member '%s' of super class '%s'", 1298 "instance member '%s' of super class '%s'",
1298 name.ToCString(), 1299 name.ToCString(),
1299 class_name.ToCString(), 1300 class_name.ToCString(),
1300 name.ToCString(), 1301 name.ToCString(),
1301 super_class_name.ToCString()); 1302 super_class_name.ToCString());
1302 } 1303 }
1303 // An implicit setter is not generated for a static field, therefore, we 1304 // An implicit setter is not generated for a static field, therefore, we
1304 // cannot rely on the code below handling the static setter case to report 1305 // cannot rely on the code below handling the static setter case to report
1305 // a conflict with an instance setter. So we check explicitly here. 1306 // a conflict with an instance setter. So we check explicitly here.
1306 setter_name = Field::SetterSymbol(name); 1307 setter_name = Field::SetterSymbol(name);
1307 super_class = FindSuperOwnerOfFunction(cls, setter_name); 1308 super_class = FindSuperOwnerOfFunction(cls, setter_name);
1308 if (!super_class.IsNull()) { 1309 if (!super_class.IsNull()) {
1309 const String& class_name = String::Handle(cls.Name()); 1310 const String& class_name = String::Handle(I, cls.Name());
1310 const String& super_class_name = String::Handle(super_class.Name()); 1311 const String& super_class_name = String::Handle(I, super_class.Name());
1311 ReportError(cls, field.token_pos(), 1312 ReportError(cls, field.token_pos(),
1312 "static field '%s' of class '%s' conflicts with " 1313 "static field '%s' of class '%s' conflicts with "
1313 "instance setter '%s=' of super class '%s'", 1314 "instance setter '%s=' of super class '%s'",
1314 name.ToCString(), 1315 name.ToCString(),
1315 class_name.ToCString(), 1316 class_name.ToCString(),
1316 name.ToCString(), 1317 name.ToCString(),
1317 super_class_name.ToCString()); 1318 super_class_name.ToCString());
1318 } 1319 }
1319 1320
1320 } else { 1321 } else {
1321 // Instance field. Check whether the field overrides a method 1322 // Instance field. Check whether the field overrides a method
1322 // (but not getter). 1323 // (but not getter).
1323 super_class = FindSuperOwnerOfFunction(cls, name); 1324 super_class = FindSuperOwnerOfFunction(cls, name);
1324 if (!super_class.IsNull()) { 1325 if (!super_class.IsNull()) {
1325 const String& class_name = String::Handle(cls.Name()); 1326 const String& class_name = String::Handle(I, cls.Name());
1326 const String& super_class_name = String::Handle(super_class.Name()); 1327 const String& super_class_name = String::Handle(I, super_class.Name());
1327 ReportError(cls, field.token_pos(), 1328 ReportError(cls, field.token_pos(),
1328 "field '%s' of class '%s' conflicts with method '%s' " 1329 "field '%s' of class '%s' conflicts with method '%s' "
1329 "of super class '%s'", 1330 "of super class '%s'",
1330 name.ToCString(), 1331 name.ToCString(),
1331 class_name.ToCString(), 1332 class_name.ToCString(),
1332 name.ToCString(), 1333 name.ToCString(),
1333 super_class_name.ToCString()); 1334 super_class_name.ToCString());
1334 } 1335 }
1335 } 1336 }
1336 if (field.is_static() && 1337 if (field.is_static() &&
1337 (field.value() != Object::null()) && 1338 (field.value() != Object::null()) &&
1338 (field.value() != Object::sentinel().raw())) { 1339 (field.value() != Object::sentinel().raw())) {
1339 // The parser does not preset the value if the type is a type parameter or 1340 // The parser does not preset the value if the type is a type parameter or
1340 // is parameterized unless the value is null. 1341 // is parameterized unless the value is null.
1341 Error& error = Error::Handle(); 1342 Error& error = Error::Handle(I);
1342 if (type.IsMalformedOrMalbounded()) { 1343 if (type.IsMalformedOrMalbounded()) {
1343 error = type.error(); 1344 error = type.error();
1344 } else { 1345 } else {
1345 ASSERT(type.IsInstantiated()); 1346 ASSERT(type.IsInstantiated());
1346 } 1347 }
1347 const Instance& const_value = Instance::Handle(field.value()); 1348 const Instance& const_value = Instance::Handle(I, field.value());
1348 if (!error.IsNull() || 1349 if (!error.IsNull() ||
1349 (!type.IsDynamicType() && 1350 (!type.IsDynamicType() &&
1350 !const_value.IsInstanceOf(type, 1351 !const_value.IsInstanceOf(type,
1351 Object::null_type_arguments(), 1352 Object::null_type_arguments(),
1352 &error))) { 1353 &error))) {
1353 if (FLAG_error_on_bad_type) { 1354 if (FLAG_error_on_bad_type) {
1354 const AbstractType& const_value_type = AbstractType::Handle( 1355 const AbstractType& const_value_type = AbstractType::Handle(
1355 const_value.GetType()); 1356 I, const_value.GetType());
1356 const String& const_value_type_name = String::Handle( 1357 const String& const_value_type_name = String::Handle(
1357 const_value_type.UserVisibleName()); 1358 I, const_value_type.UserVisibleName());
1358 const String& type_name = String::Handle(type.UserVisibleName()); 1359 const String& type_name = String::Handle(I, type.UserVisibleName());
1359 ReportErrors(error, cls, field.token_pos(), 1360 ReportErrors(error, cls, field.token_pos(),
1360 "error initializing static %s field '%s': " 1361 "error initializing static %s field '%s': "
1361 "type '%s' is not a subtype of type '%s'", 1362 "type '%s' is not a subtype of type '%s'",
1362 field.is_const() ? "const" : "final", 1363 field.is_const() ? "const" : "final",
1363 name.ToCString(), 1364 name.ToCString(),
1364 const_value_type_name.ToCString(), 1365 const_value_type_name.ToCString(),
1365 type_name.ToCString()); 1366 type_name.ToCString());
1366 } else { 1367 } else {
1367 // Do not report an error yet, even in checked mode, since the field 1368 // Do not report an error yet, even in checked mode, since the field
1368 // may not actually be used. 1369 // may not actually be used.
1369 // Also, we may be generating a snapshot in production mode that will 1370 // Also, we may be generating a snapshot in production mode that will
1370 // later be executed in checked mode, in which case an error needs to 1371 // later be executed in checked mode, in which case an error needs to
1371 // be reported, should the field be accessed. 1372 // be reported, should the field be accessed.
1372 // Therefore, we undo the optimization performed by the parser, i.e. 1373 // Therefore, we undo the optimization performed by the parser, i.e.
1373 // we create an implicit static final getter and reset the field value 1374 // we create an implicit static final getter and reset the field value
1374 // to the sentinel value. 1375 // to the sentinel value.
1375 const Function& getter = Function::Handle( 1376 const Function& getter = Function::Handle(
1377 I,
1376 Function::New(getter_name, 1378 Function::New(getter_name,
1377 RawFunction::kImplicitStaticFinalGetter, 1379 RawFunction::kImplicitStaticFinalGetter,
1378 /* is_static = */ true, 1380 /* is_static = */ true,
1379 /* is_const = */ field.is_const(), 1381 /* is_const = */ field.is_const(),
1380 /* is_abstract = */ false, 1382 /* is_abstract = */ false,
1381 /* is_external = */ false, 1383 /* is_external = */ false,
1382 /* is_native = */ false, 1384 /* is_native = */ false,
1383 cls, 1385 cls,
1384 field.token_pos())); 1386 field.token_pos()));
1385 getter.set_result_type(type); 1387 getter.set_result_type(type);
1386 cls.AddFunction(getter); 1388 cls.AddFunction(getter);
1387 field.set_value(Instance::Handle(Object::sentinel().raw())); 1389 field.set_value(Instance::Handle(I, Object::sentinel().raw()));
1388 } 1390 }
1389 } 1391 }
1390 } 1392 }
1391 } 1393 }
1392 // Collect interfaces, super interfaces, and super classes of this class. 1394 // Collect interfaces, super interfaces, and super classes of this class.
1393 const GrowableObjectArray& interfaces = 1395 const GrowableObjectArray& interfaces =
1394 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1396 GrowableObjectArray::Handle(I, GrowableObjectArray::New());
1395 CollectInterfaces(cls, interfaces); 1397 CollectInterfaces(cls, interfaces);
1396 // Include superclasses in list of interfaces and super interfaces. 1398 // Include superclasses in list of interfaces and super interfaces.
1397 super_class = cls.SuperClass(); 1399 super_class = cls.SuperClass();
1398 while (!super_class.IsNull()) { 1400 while (!super_class.IsNull()) {
1399 interfaces.Add(super_class); 1401 interfaces.Add(super_class);
1400 CollectInterfaces(super_class, interfaces); 1402 CollectInterfaces(super_class, interfaces);
1401 super_class = super_class.SuperClass(); 1403 super_class = super_class.SuperClass();
1402 } 1404 }
1403 // Resolve function signatures and check for conflicts in super classes and 1405 // Resolve function signatures and check for conflicts in super classes and
1404 // interfaces. 1406 // interfaces.
1405 array = cls.functions(); 1407 array = cls.functions();
1406 Function& function = Function::Handle(); 1408 Function& function = Function::Handle(I);
1407 Function& overridden_function = Function::Handle(); 1409 Function& overridden_function = Function::Handle(I);
1408 const intptr_t num_functions = array.Length(); 1410 const intptr_t num_functions = array.Length();
1409 Error& error = Error::Handle(); 1411 Error& error = Error::Handle(I);
1410 for (intptr_t i = 0; i < num_functions; i++) { 1412 for (intptr_t i = 0; i < num_functions; i++) {
1411 function ^= array.At(i); 1413 function ^= array.At(i);
1412 ResolveAndFinalizeSignature(cls, function); 1414 ResolveAndFinalizeSignature(cls, function);
1413 name = function.name(); 1415 name = function.name();
1414 if (FLAG_error_on_bad_override && // Report signature conflicts only. 1416 if (FLAG_error_on_bad_override && // Report signature conflicts only.
1415 !function.is_static() && !function.IsConstructor()) { 1417 !function.is_static() && !function.IsConstructor()) {
1416 // A constructor cannot override anything. 1418 // A constructor cannot override anything.
1417 for (intptr_t i = 0; i < interfaces.Length(); i++) { 1419 for (intptr_t i = 0; i < interfaces.Length(); i++) {
1418 super_class ^= interfaces.At(i); 1420 super_class ^= interfaces.At(i);
1419 // Finalize superclass since overrides check relies on all members 1421 // Finalize superclass since overrides check relies on all members
1420 // of the superclass to be finalized. 1422 // of the superclass to be finalized.
1421 FinalizeClass(super_class); 1423 FinalizeClass(super_class);
1422 overridden_function = super_class.LookupDynamicFunction(name); 1424 overridden_function = super_class.LookupDynamicFunction(name);
1423 if (!overridden_function.IsNull() && 1425 if (!overridden_function.IsNull() &&
1424 !function.HasCompatibleParametersWith(overridden_function, 1426 !function.HasCompatibleParametersWith(overridden_function,
1425 &error)) { 1427 &error)) {
1426 const String& class_name = String::Handle(cls.Name()); 1428 const String& class_name = String::Handle(I, cls.Name());
1427 const String& super_class_name = String::Handle(super_class.Name()); 1429 const String& super_class_name =
1430 String::Handle(I, super_class.Name());
1428 ReportErrors(error, cls, function.token_pos(), 1431 ReportErrors(error, cls, function.token_pos(),
1429 "class '%s' overrides method '%s' of super " 1432 "class '%s' overrides method '%s' of super "
1430 "class '%s' with incompatible parameters", 1433 "class '%s' with incompatible parameters",
1431 class_name.ToCString(), 1434 class_name.ToCString(),
1432 name.ToCString(), 1435 name.ToCString(),
1433 super_class_name.ToCString()); 1436 super_class_name.ToCString());
1434 } 1437 }
1435 } 1438 }
1436 } 1439 }
1437 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { 1440 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) {
1438 if (function.is_static()) { 1441 if (function.is_static()) {
1439 super_class = FindSuperOwnerOfFunction(cls, name); 1442 super_class = FindSuperOwnerOfFunction(cls, name);
1440 if (!super_class.IsNull()) { 1443 if (!super_class.IsNull()) {
1441 const String& class_name = String::Handle(cls.Name()); 1444 const String& class_name = String::Handle(I, cls.Name());
1442 const String& super_class_name = String::Handle(super_class.Name()); 1445 const String& super_class_name =
1446 String::Handle(I, super_class.Name());
1443 ReportError(cls, function.token_pos(), 1447 ReportError(cls, function.token_pos(),
1444 "static setter '%s=' of class '%s' conflicts with " 1448 "static setter '%s=' of class '%s' conflicts with "
1445 "instance setter '%s=' of super class '%s'", 1449 "instance setter '%s=' of super class '%s'",
1446 name.ToCString(), 1450 name.ToCString(),
1447 class_name.ToCString(), 1451 class_name.ToCString(),
1448 name.ToCString(), 1452 name.ToCString(),
1449 super_class_name.ToCString()); 1453 super_class_name.ToCString());
1450 } 1454 }
1451 } 1455 }
1452 continue; 1456 continue;
1453 } 1457 }
1454 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { 1458 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) {
1455 getter_name = name.raw(); 1459 getter_name = name.raw();
1456 name = Field::NameFromGetter(getter_name); 1460 name = Field::NameFromGetter(getter_name);
1457 } else { 1461 } else {
1458 getter_name = Field::GetterSymbol(name); 1462 getter_name = Field::GetterSymbol(name);
1459 } 1463 }
1460 if (function.is_static()) { 1464 if (function.is_static()) {
1461 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); 1465 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name);
1462 if (!super_class.IsNull()) { 1466 if (!super_class.IsNull()) {
1463 const String& class_name = String::Handle(cls.Name()); 1467 const String& class_name = String::Handle(I, cls.Name());
1464 const String& super_class_name = String::Handle(super_class.Name()); 1468 const String& super_class_name = String::Handle(I, super_class.Name());
1465 ReportError(cls, function.token_pos(), 1469 ReportError(cls, function.token_pos(),
1466 "static %s '%s' of class '%s' conflicts with " 1470 "static %s '%s' of class '%s' conflicts with "
1467 "instance member '%s' of super class '%s'", 1471 "instance member '%s' of super class '%s'",
1468 (function.IsGetterFunction() || 1472 (function.IsGetterFunction() ||
1469 function.IsImplicitGetterFunction()) ? "getter" : "method", 1473 function.IsImplicitGetterFunction()) ? "getter" : "method",
1470 name.ToCString(), 1474 name.ToCString(),
1471 class_name.ToCString(), 1475 class_name.ToCString(),
1472 name.ToCString(), 1476 name.ToCString(),
1473 super_class_name.ToCString()); 1477 super_class_name.ToCString());
1474 } 1478 }
1475 if (function.IsRedirectingFactory()) { 1479 if (function.IsRedirectingFactory()) {
1476 // The function may be a still unresolved redirecting factory. Do not 1480 // The function may be a still unresolved redirecting factory. Do not
1477 // yet try to resolve it in order to avoid cycles in class finalization. 1481 // yet try to resolve it in order to avoid cycles in class finalization.
1478 // However, the redirection type should be finalized. 1482 // However, the redirection type should be finalized.
1479 Type& type = Type::Handle(function.RedirectionType()); 1483 Type& type = Type::Handle(I, function.RedirectionType());
1480 type ^= FinalizeType(cls, type, kCanonicalize); 1484 type ^= FinalizeType(cls, type, kCanonicalize);
1481 function.SetRedirectionType(type); 1485 function.SetRedirectionType(type);
1482 } 1486 }
1483 } else if (function.IsGetterFunction() || 1487 } else if (function.IsGetterFunction() ||
1484 function.IsImplicitGetterFunction()) { 1488 function.IsImplicitGetterFunction()) {
1485 super_class = FindSuperOwnerOfFunction(cls, name); 1489 super_class = FindSuperOwnerOfFunction(cls, name);
1486 if (!super_class.IsNull()) { 1490 if (!super_class.IsNull()) {
1487 const String& class_name = String::Handle(cls.Name()); 1491 const String& class_name = String::Handle(I, cls.Name());
1488 const String& super_class_name = String::Handle(super_class.Name()); 1492 const String& super_class_name = String::Handle(I, super_class.Name());
1489 ReportError(cls, function.token_pos(), 1493 ReportError(cls, function.token_pos(),
1490 "getter '%s' of class '%s' conflicts with " 1494 "getter '%s' of class '%s' conflicts with "
1491 "method '%s' of super class '%s'", 1495 "method '%s' of super class '%s'",
1492 name.ToCString(), 1496 name.ToCString(),
1493 class_name.ToCString(), 1497 class_name.ToCString(),
1494 name.ToCString(), 1498 name.ToCString(),
1495 super_class_name.ToCString()); 1499 super_class_name.ToCString());
1496 } 1500 }
1497 } else if (!function.IsSetterFunction() && 1501 } else if (!function.IsSetterFunction() &&
1498 !function.IsImplicitSetterFunction()) { 1502 !function.IsImplicitSetterFunction()) {
1499 // A function cannot conflict with a setter, since they cannot 1503 // A function cannot conflict with a setter, since they cannot
1500 // have the same name. Thus, we do not need to check setters. 1504 // have the same name. Thus, we do not need to check setters.
1501 super_class = FindSuperOwnerOfFunction(cls, getter_name); 1505 super_class = FindSuperOwnerOfFunction(cls, getter_name);
1502 if (!super_class.IsNull()) { 1506 if (!super_class.IsNull()) {
1503 const String& class_name = String::Handle(cls.Name()); 1507 const String& class_name = String::Handle(I, cls.Name());
1504 const String& super_class_name = String::Handle(super_class.Name()); 1508 const String& super_class_name = String::Handle(I, super_class.Name());
1505 ReportError(cls, function.token_pos(), 1509 ReportError(cls, function.token_pos(),
1506 "method '%s' of class '%s' conflicts with " 1510 "method '%s' of class '%s' conflicts with "
1507 "getter '%s' of super class '%s'", 1511 "getter '%s' of super class '%s'",
1508 name.ToCString(), 1512 name.ToCString(),
1509 class_name.ToCString(), 1513 class_name.ToCString(),
1510 name.ToCString(), 1514 name.ToCString(),
1511 super_class_name.ToCString()); 1515 super_class_name.ToCString());
1512 } 1516 }
1513 } 1517 }
1514 } 1518 }
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after
3071 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); 3075 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields());
3072 field ^= fields_array.At(0); 3076 field ^= fields_array.At(0);
3073 ASSERT(field.Offset() == ByteBuffer::data_offset()); 3077 ASSERT(field.Offset() == ByteBuffer::data_offset());
3074 name ^= field.name(); 3078 name ^= field.name();
3075 expected_name ^= String::New("_data"); 3079 expected_name ^= String::New("_data");
3076 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3080 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
3077 #endif 3081 #endif
3078 } 3082 }
3079 3083
3080 } // namespace dart 3084 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698