| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include "natives.h" | 39 #include "natives.h" |
| 40 #include "scanner.h" | 40 #include "scanner.h" |
| 41 #include "scopeinfo.h" | 41 #include "scopeinfo.h" |
| 42 #include "snapshot.h" | 42 #include "snapshot.h" |
| 43 #include "v8threads.h" | 43 #include "v8threads.h" |
| 44 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP | 44 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP |
| 45 #include "regexp-macro-assembler.h" | 45 #include "regexp-macro-assembler.h" |
| 46 #include "arm/regexp-macro-assembler-arm.h" | 46 #include "arm/regexp-macro-assembler-arm.h" |
| 47 #endif | 47 #endif |
| 48 | 48 |
| 49 // Since we're converting Heap over in stages, this file is in a strange state | |
| 50 // with regard to static/nonstatic methods. THIS refers to this in a | |
| 51 // method that will eventually become non-static. HEAP should be used in | |
| 52 // methods that will remain static. | |
| 53 #define THIS HEAP | |
| 54 | |
| 55 namespace v8 { | 49 namespace v8 { |
| 56 namespace internal { | 50 namespace internal { |
| 57 | 51 |
| 58 | 52 |
| 59 static const int kMinimumPromotionLimit = 2*MB; | 53 static const int kMinimumPromotionLimit = 2*MB; |
| 60 static const int kMinimumAllocationLimit = 8*MB; | 54 static const int kMinimumAllocationLimit = 8*MB; |
| 61 | 55 |
| 62 | 56 |
| 63 Heap::Heap() | 57 Heap::Heap() |
| 64 : isolate_(NULL), | 58 : isolate_(NULL), |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 | 349 |
| 356 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); | 350 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); |
| 357 if (FLAG_print_handles) PrintHandles(); | 351 if (FLAG_print_handles) PrintHandles(); |
| 358 if (FLAG_gc_verbose) Print(); | 352 if (FLAG_gc_verbose) Print(); |
| 359 if (FLAG_code_stats) ReportCodeStatistics("After GC"); | 353 if (FLAG_code_stats) ReportCodeStatistics("After GC"); |
| 360 #endif | 354 #endif |
| 361 | 355 |
| 362 isolate_->counters()->alive_after_last_gc()->Set(SizeOfObjects()); | 356 isolate_->counters()->alive_after_last_gc()->Set(SizeOfObjects()); |
| 363 | 357 |
| 364 isolate_->counters()->symbol_table_capacity()->Set( | 358 isolate_->counters()->symbol_table_capacity()->Set( |
| 365 THIS->symbol_table()->Capacity()); | 359 symbol_table()->Capacity()); |
| 366 isolate_->counters()->number_of_symbols()->Set( | 360 isolate_->counters()->number_of_symbols()->Set( |
| 367 THIS->symbol_table()->NumberOfElements()); | 361 symbol_table()->NumberOfElements()); |
| 368 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 362 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
| 369 ReportStatisticsAfterGC(); | 363 ReportStatisticsAfterGC(); |
| 370 #endif | 364 #endif |
| 371 #ifdef ENABLE_DEBUGGER_SUPPORT | 365 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 372 isolate_->debug()->AfterGarbageCollection(); | 366 isolate_->debug()->AfterGarbageCollection(); |
| 373 #endif | 367 #endif |
| 374 } | 368 } |
| 375 | 369 |
| 376 | 370 |
| 377 void Heap::CollectAllGarbage(bool force_compaction) { | 371 void Heap::CollectAllGarbage(bool force_compaction) { |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 isolate_->context_slot_cache()->Clear(); | 742 isolate_->context_slot_cache()->Clear(); |
| 749 isolate_->descriptor_lookup_cache()->Clear(); | 743 isolate_->descriptor_lookup_cache()->Clear(); |
| 750 | 744 |
| 751 isolate_->compilation_cache()->MarkCompactPrologue(); | 745 isolate_->compilation_cache()->MarkCompactPrologue(); |
| 752 | 746 |
| 753 isolate_->MarkCompactPrologue(is_compacting); | 747 isolate_->MarkCompactPrologue(is_compacting); |
| 754 isolate_->thread_manager()->MarkCompactPrologue(is_compacting); | 748 isolate_->thread_manager()->MarkCompactPrologue(is_compacting); |
| 755 | 749 |
| 756 CompletelyClearInstanceofCache(); | 750 CompletelyClearInstanceofCache(); |
| 757 | 751 |
| 758 if (is_compacting) THIS->FlushNumberStringCache(); | 752 if (is_compacting) FlushNumberStringCache(); |
| 759 } | 753 } |
| 760 | 754 |
| 761 | 755 |
| 762 void Heap::MarkCompactEpilogue(bool is_compacting) { | 756 void Heap::MarkCompactEpilogue(bool is_compacting) { |
| 763 isolate_->MarkCompactEpilogue(is_compacting); | 757 isolate_->MarkCompactEpilogue(is_compacting); |
| 764 isolate_->thread_manager()->MarkCompactEpilogue(is_compacting); | 758 isolate_->thread_manager()->MarkCompactEpilogue(is_compacting); |
| 765 } | 759 } |
| 766 | 760 |
| 767 | 761 |
| 768 Object* Heap::FindCodeObject(Address a) { | 762 Object* Heap::FindCodeObject(Address a) { |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 HEAP->ScavengeObject(p, *p); | 1350 HEAP->ScavengeObject(p, *p); |
| 1357 } | 1351 } |
| 1358 | 1352 |
| 1359 | 1353 |
| 1360 Object* Heap::AllocatePartialMap(InstanceType instance_type, | 1354 Object* Heap::AllocatePartialMap(InstanceType instance_type, |
| 1361 int instance_size) { | 1355 int instance_size) { |
| 1362 Object* result = AllocateRawMap(); | 1356 Object* result = AllocateRawMap(); |
| 1363 if (result->IsFailure()) return result; | 1357 if (result->IsFailure()) return result; |
| 1364 | 1358 |
| 1365 // Map::cast cannot be used due to uninitialized map field. | 1359 // Map::cast cannot be used due to uninitialized map field. |
| 1366 reinterpret_cast<Map*>(result)->set_map(THIS->raw_unchecked_meta_map()); | 1360 reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map()); |
| 1367 reinterpret_cast<Map*>(result)->set_instance_type(instance_type); | 1361 reinterpret_cast<Map*>(result)->set_instance_type(instance_type); |
| 1368 reinterpret_cast<Map*>(result)->set_instance_size(instance_size); | 1362 reinterpret_cast<Map*>(result)->set_instance_size(instance_size); |
| 1369 reinterpret_cast<Map*>(result)-> | 1363 reinterpret_cast<Map*>(result)-> |
| 1370 set_scavenger(GetScavenger(instance_type, instance_size)); | 1364 set_scavenger(GetScavenger(instance_type, instance_size)); |
| 1371 reinterpret_cast<Map*>(result)->set_inobject_properties(0); | 1365 reinterpret_cast<Map*>(result)->set_inobject_properties(0); |
| 1372 reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0); | 1366 reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0); |
| 1373 reinterpret_cast<Map*>(result)->set_unused_property_fields(0); | 1367 reinterpret_cast<Map*>(result)->set_unused_property_fields(0); |
| 1374 reinterpret_cast<Map*>(result)->set_bit_field(0); | 1368 reinterpret_cast<Map*>(result)->set_bit_field(0); |
| 1375 reinterpret_cast<Map*>(result)->set_bit_field2(0); | 1369 reinterpret_cast<Map*>(result)->set_bit_field2(0); |
| 1376 return result; | 1370 return result; |
| 1377 } | 1371 } |
| 1378 | 1372 |
| 1379 | 1373 |
| 1380 Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) { | 1374 Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) { |
| 1381 Object* result = AllocateRawMap(); | 1375 Object* result = AllocateRawMap(); |
| 1382 if (result->IsFailure()) return result; | 1376 if (result->IsFailure()) return result; |
| 1383 | 1377 |
| 1384 Map* map = reinterpret_cast<Map*>(result); | 1378 Map* map = reinterpret_cast<Map*>(result); |
| 1385 map->set_map(THIS->meta_map()); | 1379 map->set_map(meta_map()); |
| 1386 map->set_instance_type(instance_type); | 1380 map->set_instance_type(instance_type); |
| 1387 map->set_scavenger(GetScavenger(instance_type, instance_size)); | 1381 map->set_scavenger(GetScavenger(instance_type, instance_size)); |
| 1388 map->set_prototype(null_value()); | 1382 map->set_prototype(null_value()); |
| 1389 map->set_constructor(null_value()); | 1383 map->set_constructor(null_value()); |
| 1390 map->set_instance_size(instance_size); | 1384 map->set_instance_size(instance_size); |
| 1391 map->set_inobject_properties(0); | 1385 map->set_inobject_properties(0); |
| 1392 map->set_pre_allocated_property_fields(0); | 1386 map->set_pre_allocated_property_fields(0); |
| 1393 map->set_instance_descriptors(THIS->empty_descriptor_array()); | 1387 map->set_instance_descriptors(empty_descriptor_array()); |
| 1394 map->set_code_cache(THIS->empty_fixed_array()); | 1388 map->set_code_cache(empty_fixed_array()); |
| 1395 map->set_unused_property_fields(0); | 1389 map->set_unused_property_fields(0); |
| 1396 map->set_bit_field(0); | 1390 map->set_bit_field(0); |
| 1397 map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements)); | 1391 map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements)); |
| 1398 | 1392 |
| 1399 // If the map object is aligned fill the padding area with Smi 0 objects. | 1393 // If the map object is aligned fill the padding area with Smi 0 objects. |
| 1400 if (Map::kPadStart < Map::kSize) { | 1394 if (Map::kPadStart < Map::kSize) { |
| 1401 memset(reinterpret_cast<byte*>(map) + Map::kPadStart - kHeapObjectTag, | 1395 memset(reinterpret_cast<byte*>(map) + Map::kPadStart - kHeapObjectTag, |
| 1402 0, | 1396 0, |
| 1403 Map::kSize - Map::kPadStart); | 1397 Map::kSize - Map::kPadStart); |
| 1404 } | 1398 } |
| 1405 return map; | 1399 return map; |
| 1406 } | 1400 } |
| 1407 | 1401 |
| 1408 | 1402 |
| 1409 Object* Heap::AllocateCodeCache() { | 1403 Object* Heap::AllocateCodeCache() { |
| 1410 Object* result = AllocateStruct(CODE_CACHE_TYPE); | 1404 Object* result = AllocateStruct(CODE_CACHE_TYPE); |
| 1411 if (result->IsFailure()) return result; | 1405 if (result->IsFailure()) return result; |
| 1412 CodeCache* code_cache = CodeCache::cast(result); | 1406 CodeCache* code_cache = CodeCache::cast(result); |
| 1413 code_cache->set_default_cache(THIS->empty_fixed_array()); | 1407 code_cache->set_default_cache(empty_fixed_array()); |
| 1414 code_cache->set_normal_type_cache(THIS->undefined_value()); | 1408 code_cache->set_normal_type_cache(undefined_value()); |
| 1415 return code_cache; | 1409 return code_cache; |
| 1416 } | 1410 } |
| 1417 | 1411 |
| 1418 | 1412 |
| 1419 const Heap::StringTypeTable Heap::string_type_table[] = { | 1413 const Heap::StringTypeTable Heap::string_type_table[] = { |
| 1420 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ | 1414 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ |
| 1421 {type, size, k##camel_name##MapRootIndex}, | 1415 {type, size, k##camel_name##MapRootIndex}, |
| 1422 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) | 1416 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) |
| 1423 #undef STRING_TYPE_ELEMENT | 1417 #undef STRING_TYPE_ELEMENT |
| 1424 }; | 1418 }; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 set_oddball_map(Map::cast(obj)); | 1451 set_oddball_map(Map::cast(obj)); |
| 1458 | 1452 |
| 1459 // Allocate the empty array. | 1453 // Allocate the empty array. |
| 1460 obj = AllocateEmptyFixedArray(); | 1454 obj = AllocateEmptyFixedArray(); |
| 1461 if (obj->IsFailure()) return false; | 1455 if (obj->IsFailure()) return false; |
| 1462 set_empty_fixed_array(FixedArray::cast(obj)); | 1456 set_empty_fixed_array(FixedArray::cast(obj)); |
| 1463 | 1457 |
| 1464 obj = Allocate(oddball_map(), OLD_DATA_SPACE); | 1458 obj = Allocate(oddball_map(), OLD_DATA_SPACE); |
| 1465 if (obj->IsFailure()) return false; | 1459 if (obj->IsFailure()) return false; |
| 1466 set_null_value(obj); | 1460 set_null_value(obj); |
| 1461 Oddball::cast(obj)->set_kind(Oddball::kNull); |
| 1467 | 1462 |
| 1468 // Allocate the empty descriptor array. | 1463 // Allocate the empty descriptor array. |
| 1469 obj = AllocateEmptyFixedArray(); | 1464 obj = AllocateEmptyFixedArray(); |
| 1470 if (obj->IsFailure()) return false; | 1465 if (obj->IsFailure()) return false; |
| 1471 set_empty_descriptor_array(DescriptorArray::cast(obj)); | 1466 set_empty_descriptor_array(DescriptorArray::cast(obj)); |
| 1472 | 1467 |
| 1473 // Fix the instance_descriptors for the existing maps. | 1468 // Fix the instance_descriptors for the existing maps. |
| 1474 meta_map()->set_instance_descriptors(empty_descriptor_array()); | 1469 meta_map()->set_instance_descriptors(empty_descriptor_array()); |
| 1475 meta_map()->set_code_cache(empty_fixed_array()); | 1470 meta_map()->set_code_cache(empty_fixed_array()); |
| 1476 | 1471 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 | 1605 |
| 1611 Object* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { | 1606 Object* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { |
| 1612 // Statically ensure that it is safe to allocate heap numbers in paged | 1607 // Statically ensure that it is safe to allocate heap numbers in paged |
| 1613 // spaces. | 1608 // spaces. |
| 1614 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); | 1609 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); |
| 1615 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 1610 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 1616 | 1611 |
| 1617 Object* result = AllocateRaw(HeapNumber::kSize, space, OLD_DATA_SPACE); | 1612 Object* result = AllocateRaw(HeapNumber::kSize, space, OLD_DATA_SPACE); |
| 1618 if (result->IsFailure()) return result; | 1613 if (result->IsFailure()) return result; |
| 1619 | 1614 |
| 1620 HeapObject::cast(result)->set_map(THIS->heap_number_map()); | 1615 HeapObject::cast(result)->set_map(heap_number_map()); |
| 1621 HeapNumber::cast(result)->set_value(value); | 1616 HeapNumber::cast(result)->set_value(value); |
| 1622 return result; | 1617 return result; |
| 1623 } | 1618 } |
| 1624 | 1619 |
| 1625 | 1620 |
| 1626 Object* Heap::AllocateHeapNumber(double value) { | 1621 Object* Heap::AllocateHeapNumber(double value) { |
| 1627 // Use general version, if we're forced to always allocate. | 1622 // Use general version, if we're forced to always allocate. |
| 1628 if (always_allocate()) return AllocateHeapNumber(value, TENURED); | 1623 if (always_allocate()) return AllocateHeapNumber(value, TENURED); |
| 1629 | 1624 |
| 1630 // This version of AllocateHeapNumber is optimized for | 1625 // This version of AllocateHeapNumber is optimized for |
| 1631 // allocation in new space. | 1626 // allocation in new space. |
| 1632 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); | 1627 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); |
| 1633 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); | 1628 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); |
| 1634 Object* result = new_space_.AllocateRaw(HeapNumber::kSize); | 1629 Object* result = new_space_.AllocateRaw(HeapNumber::kSize); |
| 1635 if (result->IsFailure()) return result; | 1630 if (result->IsFailure()) return result; |
| 1636 HeapObject::cast(result)->set_map(THIS->heap_number_map()); | 1631 HeapObject::cast(result)->set_map(heap_number_map()); |
| 1637 HeapNumber::cast(result)->set_value(value); | 1632 HeapNumber::cast(result)->set_value(value); |
| 1638 return result; | 1633 return result; |
| 1639 } | 1634 } |
| 1640 | 1635 |
| 1641 | 1636 |
| 1642 Object* Heap::AllocateJSGlobalPropertyCell(Object* value) { | 1637 Object* Heap::AllocateJSGlobalPropertyCell(Object* value) { |
| 1643 Object* result = AllocateRawCell(); | 1638 Object* result = AllocateRawCell(); |
| 1644 if (result->IsFailure()) return result; | 1639 if (result->IsFailure()) return result; |
| 1645 HeapObject::cast(result)->set_map(THIS->global_property_cell_map()); | 1640 HeapObject::cast(result)->set_map(global_property_cell_map()); |
| 1646 JSGlobalPropertyCell::cast(result)->set_value(value); | 1641 JSGlobalPropertyCell::cast(result)->set_value(value); |
| 1647 return result; | 1642 return result; |
| 1648 } | 1643 } |
| 1649 | 1644 |
| 1650 | 1645 |
| 1651 Object* Heap::CreateOddball(const char* to_string, | 1646 Object* Heap::CreateOddball(const char* to_string, |
| 1652 Object* to_number) { | 1647 Object* to_number, |
| 1648 byte kind) { |
| 1653 Object* result = Allocate(oddball_map(), OLD_DATA_SPACE); | 1649 Object* result = Allocate(oddball_map(), OLD_DATA_SPACE); |
| 1654 if (result->IsFailure()) return result; | 1650 if (result->IsFailure()) return result; |
| 1655 return Oddball::cast(result)->Initialize(to_string, to_number); | 1651 return Oddball::cast(result)->Initialize(to_string, to_number, kind); |
| 1656 } | 1652 } |
| 1657 | 1653 |
| 1658 | 1654 |
| 1659 bool Heap::CreateApiObjects() { | 1655 bool Heap::CreateApiObjects() { |
| 1660 Object* obj; | 1656 Object* obj; |
| 1661 | 1657 |
| 1662 obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 1658 obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 1663 if (obj->IsFailure()) return false; | 1659 if (obj->IsFailure()) return false; |
| 1664 set_neander_map(Map::cast(obj)); | 1660 set_neander_map(Map::cast(obj)); |
| 1665 | 1661 |
| 1666 obj = AllocateJSObjectFromMap(THIS->neander_map()); | 1662 obj = AllocateJSObjectFromMap(neander_map()); |
| 1667 if (obj->IsFailure()) return false; | 1663 if (obj->IsFailure()) return false; |
| 1668 Object* elements = AllocateFixedArray(2); | 1664 Object* elements = AllocateFixedArray(2); |
| 1669 if (elements->IsFailure()) return false; | 1665 if (elements->IsFailure()) return false; |
| 1670 FixedArray::cast(elements)->set(0, Smi::FromInt(0)); | 1666 FixedArray::cast(elements)->set(0, Smi::FromInt(0)); |
| 1671 JSObject::cast(obj)->set_elements(FixedArray::cast(elements)); | 1667 JSObject::cast(obj)->set_elements(FixedArray::cast(elements)); |
| 1672 set_message_listeners(JSObject::cast(obj)); | 1668 set_message_listeners(JSObject::cast(obj)); |
| 1673 | 1669 |
| 1674 return true; | 1670 return true; |
| 1675 } | 1671 } |
| 1676 | 1672 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 set_minus_zero_value(obj); | 1729 set_minus_zero_value(obj); |
| 1734 ASSERT(signbit(minus_zero_value()->Number()) != 0); | 1730 ASSERT(signbit(minus_zero_value()->Number()) != 0); |
| 1735 | 1731 |
| 1736 obj = AllocateHeapNumber(OS::nan_value(), TENURED); | 1732 obj = AllocateHeapNumber(OS::nan_value(), TENURED); |
| 1737 if (obj->IsFailure()) return false; | 1733 if (obj->IsFailure()) return false; |
| 1738 set_nan_value(obj); | 1734 set_nan_value(obj); |
| 1739 | 1735 |
| 1740 obj = Allocate(oddball_map(), OLD_DATA_SPACE); | 1736 obj = Allocate(oddball_map(), OLD_DATA_SPACE); |
| 1741 if (obj->IsFailure()) return false; | 1737 if (obj->IsFailure()) return false; |
| 1742 set_undefined_value(obj); | 1738 set_undefined_value(obj); |
| 1739 Oddball::cast(obj)->set_kind(Oddball::kUndefined); |
| 1743 ASSERT(!InNewSpace(undefined_value())); | 1740 ASSERT(!InNewSpace(undefined_value())); |
| 1744 | 1741 |
| 1745 // Allocate initial symbol table. | 1742 // Allocate initial symbol table. |
| 1746 obj = SymbolTable::Allocate(kInitialSymbolTableSize); | 1743 obj = SymbolTable::Allocate(kInitialSymbolTableSize); |
| 1747 if (obj->IsFailure()) return false; | 1744 if (obj->IsFailure()) return false; |
| 1748 // Don't use set_symbol_table() due to asserts. | 1745 // Don't use set_symbol_table() due to asserts. |
| 1749 roots_[kSymbolTableRootIndex] = obj; | 1746 roots_[kSymbolTableRootIndex] = obj; |
| 1750 | 1747 |
| 1751 // Assign the print strings for oddballs after creating symboltable. | 1748 // Assign the print strings for oddballs after creating symboltable. |
| 1752 Object* symbol = LookupAsciiSymbol("undefined"); | 1749 Object* symbol = LookupAsciiSymbol("undefined"); |
| 1753 if (symbol->IsFailure()) return false; | 1750 if (symbol->IsFailure()) return false; |
| 1754 Oddball::cast(undefined_value())->set_to_string(String::cast(symbol)); | 1751 Oddball::cast(undefined_value())->set_to_string(String::cast(symbol)); |
| 1755 Oddball::cast(undefined_value())->set_to_number(nan_value()); | 1752 Oddball::cast(undefined_value())->set_to_number(nan_value()); |
| 1756 | 1753 |
| 1757 // Allocate the null_value | 1754 // Allocate the null_value |
| 1758 obj = Oddball::cast(null_value())->Initialize("null", Smi::FromInt(0)); | 1755 obj = Oddball::cast(null_value())->Initialize("null", |
| 1756 Smi::FromInt(0), |
| 1757 Oddball::kNull); |
| 1759 if (obj->IsFailure()) return false; | 1758 if (obj->IsFailure()) return false; |
| 1760 | 1759 |
| 1761 obj = CreateOddball("true", Smi::FromInt(1)); | 1760 obj = CreateOddball("true", Smi::FromInt(1), Oddball::kTrue); |
| 1762 if (obj->IsFailure()) return false; | 1761 if (obj->IsFailure()) return false; |
| 1763 set_true_value(obj); | 1762 set_true_value(obj); |
| 1764 | 1763 |
| 1765 obj = CreateOddball("false", Smi::FromInt(0)); | 1764 obj = CreateOddball("false", Smi::FromInt(0), Oddball::kFalse); |
| 1766 if (obj->IsFailure()) return false; | 1765 if (obj->IsFailure()) return false; |
| 1767 set_false_value(obj); | 1766 set_false_value(obj); |
| 1768 | 1767 |
| 1769 obj = CreateOddball("hole", Smi::FromInt(-1)); | 1768 obj = CreateOddball("hole", Smi::FromInt(-1), Oddball::kTheHole); |
| 1770 if (obj->IsFailure()) return false; | 1769 if (obj->IsFailure()) return false; |
| 1771 set_the_hole_value(obj); | 1770 set_the_hole_value(obj); |
| 1772 | 1771 |
| 1773 obj = CreateOddball("no_interceptor_result_sentinel", Smi::FromInt(-2)); | 1772 obj = CreateOddball("no_interceptor_result_sentinel", |
| 1773 Smi::FromInt(-2), |
| 1774 Oddball::kOther); |
| 1774 if (obj->IsFailure()) return false; | 1775 if (obj->IsFailure()) return false; |
| 1775 set_no_interceptor_result_sentinel(obj); | 1776 set_no_interceptor_result_sentinel(obj); |
| 1776 | 1777 |
| 1777 obj = CreateOddball("termination_exception", Smi::FromInt(-3)); | 1778 obj = CreateOddball("termination_exception", |
| 1779 Smi::FromInt(-3), |
| 1780 Oddball::kOther); |
| 1778 if (obj->IsFailure()) return false; | 1781 if (obj->IsFailure()) return false; |
| 1779 set_termination_exception(obj); | 1782 set_termination_exception(obj); |
| 1780 | 1783 |
| 1781 // Allocate the empty string. | 1784 // Allocate the empty string. |
| 1782 obj = AllocateRawAsciiString(0, TENURED); | 1785 obj = AllocateRawAsciiString(0, TENURED); |
| 1783 if (obj->IsFailure()) return false; | 1786 if (obj->IsFailure()) return false; |
| 1784 set_empty_string(String::cast(obj)); | 1787 set_empty_string(String::cast(obj)); |
| 1785 | 1788 |
| 1786 for (unsigned i = 0; i < ARRAY_SIZE(constant_symbol_table); i++) { | 1789 for (unsigned i = 0; i < ARRAY_SIZE(constant_symbol_table); i++) { |
| 1787 obj = LookupAsciiSymbol(constant_symbol_table[i].contents); | 1790 obj = LookupAsciiSymbol(constant_symbol_table[i].contents); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 int number_string_cache_size = max_semispace_size_ / 512; | 1863 int number_string_cache_size = max_semispace_size_ / 512; |
| 1861 number_string_cache_size = Max(32, Min(16*KB, number_string_cache_size)); | 1864 number_string_cache_size = Max(32, Min(16*KB, number_string_cache_size)); |
| 1862 Object* obj = AllocateFixedArray(number_string_cache_size * 2, TENURED); | 1865 Object* obj = AllocateFixedArray(number_string_cache_size * 2, TENURED); |
| 1863 if (!obj->IsFailure()) set_number_string_cache(FixedArray::cast(obj)); | 1866 if (!obj->IsFailure()) set_number_string_cache(FixedArray::cast(obj)); |
| 1864 return obj; | 1867 return obj; |
| 1865 } | 1868 } |
| 1866 | 1869 |
| 1867 | 1870 |
| 1868 void Heap::FlushNumberStringCache() { | 1871 void Heap::FlushNumberStringCache() { |
| 1869 // Flush the number to string cache. | 1872 // Flush the number to string cache. |
| 1870 int len = THIS->number_string_cache()->length(); | 1873 int len = number_string_cache()->length(); |
| 1871 for (int i = 0; i < len; i++) { | 1874 for (int i = 0; i < len; i++) { |
| 1872 THIS->number_string_cache()->set_undefined(i); | 1875 number_string_cache()->set_undefined(i); |
| 1873 } | 1876 } |
| 1874 } | 1877 } |
| 1875 | 1878 |
| 1876 | 1879 |
| 1877 static inline int double_get_hash(double d) { | 1880 static inline int double_get_hash(double d) { |
| 1878 DoubleRepresentation rep(d); | 1881 DoubleRepresentation rep(d); |
| 1879 return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32); | 1882 return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32); |
| 1880 } | 1883 } |
| 1881 | 1884 |
| 1882 | 1885 |
| 1883 static inline int smi_get_hash(Smi* smi) { | 1886 static inline int smi_get_hash(Smi* smi) { |
| 1884 return smi->value(); | 1887 return smi->value(); |
| 1885 } | 1888 } |
| 1886 | 1889 |
| 1887 | 1890 |
| 1888 Object* Heap::GetNumberStringCache(Object* number) { | 1891 Object* Heap::GetNumberStringCache(Object* number) { |
| 1889 int hash; | 1892 int hash; |
| 1890 int mask = (THIS->number_string_cache()->length() >> 1) - 1; | 1893 int mask = (number_string_cache()->length() >> 1) - 1; |
| 1891 if (number->IsSmi()) { | 1894 if (number->IsSmi()) { |
| 1892 hash = smi_get_hash(Smi::cast(number)) & mask; | 1895 hash = smi_get_hash(Smi::cast(number)) & mask; |
| 1893 } else { | 1896 } else { |
| 1894 hash = double_get_hash(number->Number()) & mask; | 1897 hash = double_get_hash(number->Number()) & mask; |
| 1895 } | 1898 } |
| 1896 Object* key = THIS->number_string_cache()->get(hash * 2); | 1899 Object* key = number_string_cache()->get(hash * 2); |
| 1897 if (key == number) { | 1900 if (key == number) { |
| 1898 return String::cast(THIS->number_string_cache()->get(hash * 2 + 1)); | 1901 return String::cast(number_string_cache()->get(hash * 2 + 1)); |
| 1899 } else if (key->IsHeapNumber() && | 1902 } else if (key->IsHeapNumber() && |
| 1900 number->IsHeapNumber() && | 1903 number->IsHeapNumber() && |
| 1901 key->Number() == number->Number()) { | 1904 key->Number() == number->Number()) { |
| 1902 return String::cast(THIS->number_string_cache()->get(hash * 2 + 1)); | 1905 return String::cast(number_string_cache()->get(hash * 2 + 1)); |
| 1903 } | 1906 } |
| 1904 return THIS->undefined_value(); | 1907 return undefined_value(); |
| 1905 } | 1908 } |
| 1906 | 1909 |
| 1907 | 1910 |
| 1908 void Heap::SetNumberStringCache(Object* number, String* string) { | 1911 void Heap::SetNumberStringCache(Object* number, String* string) { |
| 1909 int hash; | 1912 int hash; |
| 1910 int mask = (THIS->number_string_cache()->length() >> 1) - 1; | 1913 int mask = (number_string_cache()->length() >> 1) - 1; |
| 1911 if (number->IsSmi()) { | 1914 if (number->IsSmi()) { |
| 1912 hash = smi_get_hash(Smi::cast(number)) & mask; | 1915 hash = smi_get_hash(Smi::cast(number)) & mask; |
| 1913 THIS->number_string_cache()->set(hash * 2, Smi::cast(number)); | 1916 number_string_cache()->set(hash * 2, Smi::cast(number)); |
| 1914 } else { | 1917 } else { |
| 1915 hash = double_get_hash(number->Number()) & mask; | 1918 hash = double_get_hash(number->Number()) & mask; |
| 1916 THIS->number_string_cache()->set(hash * 2, number); | 1919 number_string_cache()->set(hash * 2, number); |
| 1917 } | 1920 } |
| 1918 THIS->number_string_cache()->set(hash * 2 + 1, string); | 1921 number_string_cache()->set(hash * 2 + 1, string); |
| 1919 } | 1922 } |
| 1920 | 1923 |
| 1921 | 1924 |
| 1922 Object* Heap::NumberToString(Object* number, bool check_number_string_cache) { | 1925 Object* Heap::NumberToString(Object* number, bool check_number_string_cache) { |
| 1923 isolate_->counters()->number_to_string_runtime()->Increment(); | 1926 isolate_->counters()->number_to_string_runtime()->Increment(); |
| 1924 if (check_number_string_cache) { | 1927 if (check_number_string_cache) { |
| 1925 Object* cached = GetNumberStringCache(number); | 1928 Object* cached = GetNumberStringCache(number); |
| 1926 if (cached != THIS->undefined_value()) { | 1929 if (cached != undefined_value()) { |
| 1927 return cached; | 1930 return cached; |
| 1928 } | 1931 } |
| 1929 } | 1932 } |
| 1930 | 1933 |
| 1931 char arr[100]; | 1934 char arr[100]; |
| 1932 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 1935 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
| 1933 const char* str; | 1936 const char* str; |
| 1934 if (number->IsSmi()) { | 1937 if (number->IsSmi()) { |
| 1935 int num = Smi::cast(number)->value(); | 1938 int num = Smi::cast(number)->value(); |
| 1936 str = IntToCString(num, buffer); | 1939 str = IntToCString(num, buffer); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 | 1996 |
| 1994 // Materialize the value in the heap. | 1997 // Materialize the value in the heap. |
| 1995 return AllocateHeapNumber(value, pretenure); | 1998 return AllocateHeapNumber(value, pretenure); |
| 1996 } | 1999 } |
| 1997 | 2000 |
| 1998 | 2001 |
| 1999 Object* Heap::AllocateProxy(Address proxy, PretenureFlag pretenure) { | 2002 Object* Heap::AllocateProxy(Address proxy, PretenureFlag pretenure) { |
| 2000 // Statically ensure that it is safe to allocate proxies in paged spaces. | 2003 // Statically ensure that it is safe to allocate proxies in paged spaces. |
| 2001 STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize); | 2004 STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize); |
| 2002 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2005 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 2003 Object* result = Allocate(THIS->proxy_map(), space); | 2006 Object* result = Allocate(proxy_map(), space); |
| 2004 if (result->IsFailure()) return result; | 2007 if (result->IsFailure()) return result; |
| 2005 | 2008 |
| 2006 Proxy::cast(result)->set_proxy(proxy); | 2009 Proxy::cast(result)->set_proxy(proxy); |
| 2007 return result; | 2010 return result; |
| 2008 } | 2011 } |
| 2009 | 2012 |
| 2010 | 2013 |
| 2011 Object* Heap::AllocateSharedFunctionInfo(Object* name) { | 2014 Object* Heap::AllocateSharedFunctionInfo(Object* name) { |
| 2012 Object* result = Allocate(THIS->shared_function_info_map(), | 2015 Object* result = Allocate(shared_function_info_map(), |
| 2013 OLD_POINTER_SPACE); | 2016 OLD_POINTER_SPACE); |
| 2014 if (result->IsFailure()) return result; | 2017 if (result->IsFailure()) return result; |
| 2015 | 2018 |
| 2016 SharedFunctionInfo* share = SharedFunctionInfo::cast(result); | 2019 SharedFunctionInfo* share = SharedFunctionInfo::cast(result); |
| 2017 share->set_name(name); | 2020 share->set_name(name); |
| 2018 Code* illegal = isolate_->builtins()->builtin(Builtins::Illegal); | 2021 Code* illegal = isolate_->builtins()->builtin(Builtins::Illegal); |
| 2019 share->set_code(illegal); | 2022 share->set_code(illegal); |
| 2020 share->set_scope_info(SerializedScopeInfo::Empty()); | 2023 share->set_scope_info(SerializedScopeInfo::Empty()); |
| 2021 Code* construct_stub = isolate_->builtins()->builtin( | 2024 Code* construct_stub = isolate_->builtins()->builtin( |
| 2022 Builtins::JSConstructStubGeneric); | 2025 Builtins::JSConstructStubGeneric); |
| 2023 share->set_construct_stub(construct_stub); | 2026 share->set_construct_stub(construct_stub); |
| 2024 share->set_expected_nof_properties(0); | 2027 share->set_expected_nof_properties(0); |
| 2025 share->set_length(0); | 2028 share->set_length(0); |
| 2026 share->set_formal_parameter_count(0); | 2029 share->set_formal_parameter_count(0); |
| 2027 share->set_instance_class_name(THIS->Object_symbol()); | 2030 share->set_instance_class_name(Object_symbol()); |
| 2028 share->set_function_data(THIS->undefined_value()); | 2031 share->set_function_data(undefined_value()); |
| 2029 share->set_script(THIS->undefined_value()); | 2032 share->set_script(undefined_value()); |
| 2030 share->set_start_position_and_type(0); | 2033 share->set_start_position_and_type(0); |
| 2031 share->set_debug_info(THIS->undefined_value()); | 2034 share->set_debug_info(undefined_value()); |
| 2032 share->set_inferred_name(THIS->empty_string()); | 2035 share->set_inferred_name(empty_string()); |
| 2033 share->set_compiler_hints(0); | 2036 share->set_compiler_hints(0); |
| 2034 share->set_this_property_assignments_count(0); | 2037 share->set_this_property_assignments_count(0); |
| 2035 share->set_this_property_assignments(THIS->undefined_value()); | 2038 share->set_this_property_assignments(undefined_value()); |
| 2036 share->set_num_literals(0); | 2039 share->set_num_literals(0); |
| 2037 share->set_end_position(0); | 2040 share->set_end_position(0); |
| 2038 share->set_function_token_position(0); | 2041 share->set_function_token_position(0); |
| 2039 return result; | 2042 return result; |
| 2040 } | 2043 } |
| 2041 | 2044 |
| 2042 | 2045 |
| 2043 // Returns true for a character in a range. Both limits are inclusive. | 2046 // Returns true for a character in a range. Both limits are inclusive. |
| 2044 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { | 2047 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { |
| 2045 // This makes uses of the the unsigned wraparound. | 2048 // This makes uses of the the unsigned wraparound. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 if (result->IsFailure()) return result; | 2166 if (result->IsFailure()) return result; |
| 2164 // Copy the characters into the new object. | 2167 // Copy the characters into the new object. |
| 2165 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | 2168 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
| 2166 String::WriteToFlat(first, dest, 0, first_length); | 2169 String::WriteToFlat(first, dest, 0, first_length); |
| 2167 String::WriteToFlat(second, dest + first_length, 0, second_length); | 2170 String::WriteToFlat(second, dest + first_length, 0, second_length); |
| 2168 return result; | 2171 return result; |
| 2169 } | 2172 } |
| 2170 } | 2173 } |
| 2171 | 2174 |
| 2172 Map* map = (is_ascii || is_ascii_data_in_two_byte_string) ? | 2175 Map* map = (is_ascii || is_ascii_data_in_two_byte_string) ? |
| 2173 THIS->cons_ascii_string_map() : THIS->cons_string_map(); | 2176 cons_ascii_string_map() : cons_string_map(); |
| 2174 | 2177 |
| 2175 Object* result = Allocate(map, NEW_SPACE); | 2178 Object* result = Allocate(map, NEW_SPACE); |
| 2176 if (result->IsFailure()) return result; | 2179 if (result->IsFailure()) return result; |
| 2177 | 2180 |
| 2178 AssertNoAllocation no_gc; | 2181 AssertNoAllocation no_gc; |
| 2179 ConsString* cons_string = ConsString::cast(result); | 2182 ConsString* cons_string = ConsString::cast(result); |
| 2180 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); | 2183 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); |
| 2181 cons_string->set_length(length); | 2184 cons_string->set_length(length); |
| 2182 cons_string->set_hash_field(String::kEmptyHashField); | 2185 cons_string->set_hash_field(String::kEmptyHashField); |
| 2183 cons_string->set_first(first, mode); | 2186 cons_string->set_first(first, mode); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 | 2230 |
| 2228 | 2231 |
| 2229 Object* Heap::AllocateExternalStringFromAscii( | 2232 Object* Heap::AllocateExternalStringFromAscii( |
| 2230 ExternalAsciiString::Resource* resource) { | 2233 ExternalAsciiString::Resource* resource) { |
| 2231 size_t length = resource->length(); | 2234 size_t length = resource->length(); |
| 2232 if (length > static_cast<size_t>(String::kMaxLength)) { | 2235 if (length > static_cast<size_t>(String::kMaxLength)) { |
| 2233 Isolate::Current()->context()->mark_out_of_memory(); | 2236 Isolate::Current()->context()->mark_out_of_memory(); |
| 2234 return Failure::OutOfMemoryException(); | 2237 return Failure::OutOfMemoryException(); |
| 2235 } | 2238 } |
| 2236 | 2239 |
| 2237 Map* map = THIS->external_ascii_string_map(); | 2240 Map* map = external_ascii_string_map(); |
| 2238 Object* result = Allocate(map, NEW_SPACE); | 2241 Object* result = Allocate(map, NEW_SPACE); |
| 2239 if (result->IsFailure()) return result; | 2242 if (result->IsFailure()) return result; |
| 2240 | 2243 |
| 2241 ExternalAsciiString* external_string = ExternalAsciiString::cast(result); | 2244 ExternalAsciiString* external_string = ExternalAsciiString::cast(result); |
| 2242 external_string->set_length(static_cast<int>(length)); | 2245 external_string->set_length(static_cast<int>(length)); |
| 2243 external_string->set_hash_field(String::kEmptyHashField); | 2246 external_string->set_hash_field(String::kEmptyHashField); |
| 2244 external_string->set_resource(resource); | 2247 external_string->set_resource(resource); |
| 2245 | 2248 |
| 2246 return result; | 2249 return result; |
| 2247 } | 2250 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2279 external_string->set_length(static_cast<int>(length)); | 2282 external_string->set_length(static_cast<int>(length)); |
| 2280 external_string->set_hash_field(String::kEmptyHashField); | 2283 external_string->set_hash_field(String::kEmptyHashField); |
| 2281 external_string->set_resource(resource); | 2284 external_string->set_resource(resource); |
| 2282 | 2285 |
| 2283 return result; | 2286 return result; |
| 2284 } | 2287 } |
| 2285 | 2288 |
| 2286 | 2289 |
| 2287 Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { | 2290 Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { |
| 2288 if (code <= String::kMaxAsciiCharCode) { | 2291 if (code <= String::kMaxAsciiCharCode) { |
| 2289 Object* value = THIS->single_character_string_cache()->get(code); | 2292 Object* value = single_character_string_cache()->get(code); |
| 2290 if (value != THIS->undefined_value()) return value; | 2293 if (value != undefined_value()) return value; |
| 2291 | 2294 |
| 2292 char buffer[1]; | 2295 char buffer[1]; |
| 2293 buffer[0] = static_cast<char>(code); | 2296 buffer[0] = static_cast<char>(code); |
| 2294 Object* result = LookupSymbol(Vector<const char>(buffer, 1)); | 2297 Object* result = LookupSymbol(Vector<const char>(buffer, 1)); |
| 2295 | 2298 |
| 2296 if (result->IsFailure()) return result; | 2299 if (result->IsFailure()) return result; |
| 2297 THIS->single_character_string_cache()->set(code, result); | 2300 single_character_string_cache()->set(code, result); |
| 2298 return result; | 2301 return result; |
| 2299 } | 2302 } |
| 2300 | 2303 |
| 2301 Object* result = AllocateRawTwoByteString(1); | 2304 Object* result = AllocateRawTwoByteString(1); |
| 2302 if (result->IsFailure()) return result; | 2305 if (result->IsFailure()) return result; |
| 2303 String* answer = String::cast(result); | 2306 String* answer = String::cast(result); |
| 2304 answer->Set(0, code); | 2307 answer->Set(0, code); |
| 2305 return answer; | 2308 return answer; |
| 2306 } | 2309 } |
| 2307 | 2310 |
| 2308 | 2311 |
| 2309 Object* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { | 2312 Object* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { |
| 2310 if (length < 0 || length > ByteArray::kMaxLength) { | 2313 if (length < 0 || length > ByteArray::kMaxLength) { |
| 2311 return Failure::OutOfMemoryException(); | 2314 return Failure::OutOfMemoryException(); |
| 2312 } | 2315 } |
| 2313 if (pretenure == NOT_TENURED) { | 2316 if (pretenure == NOT_TENURED) { |
| 2314 return AllocateByteArray(length); | 2317 return AllocateByteArray(length); |
| 2315 } | 2318 } |
| 2316 int size = ByteArray::SizeFor(length); | 2319 int size = ByteArray::SizeFor(length); |
| 2317 Object* result = (size <= MaxObjectSizeInPagedSpace()) | 2320 Object* result = (size <= MaxObjectSizeInPagedSpace()) |
| 2318 ? old_data_space_->AllocateRaw(size) | 2321 ? old_data_space_->AllocateRaw(size) |
| 2319 : lo_space_->AllocateRaw(size); | 2322 : lo_space_->AllocateRaw(size); |
| 2320 if (result->IsFailure()) return result; | 2323 if (result->IsFailure()) return result; |
| 2321 | 2324 |
| 2322 reinterpret_cast<ByteArray*>(result)->set_map(THIS->byte_array_map()); | 2325 reinterpret_cast<ByteArray*>(result)->set_map(byte_array_map()); |
| 2323 reinterpret_cast<ByteArray*>(result)->set_length(length); | 2326 reinterpret_cast<ByteArray*>(result)->set_length(length); |
| 2324 return result; | 2327 return result; |
| 2325 } | 2328 } |
| 2326 | 2329 |
| 2327 | 2330 |
| 2328 Object* Heap::AllocateByteArray(int length) { | 2331 Object* Heap::AllocateByteArray(int length) { |
| 2329 if (length < 0 || length > ByteArray::kMaxLength) { | 2332 if (length < 0 || length > ByteArray::kMaxLength) { |
| 2330 return Failure::OutOfMemoryException(); | 2333 return Failure::OutOfMemoryException(); |
| 2331 } | 2334 } |
| 2332 int size = ByteArray::SizeFor(length); | 2335 int size = ByteArray::SizeFor(length); |
| 2333 AllocationSpace space = | 2336 AllocationSpace space = |
| 2334 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : NEW_SPACE; | 2337 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : NEW_SPACE; |
| 2335 Object* result = AllocateRaw(size, space, OLD_DATA_SPACE); | 2338 Object* result = AllocateRaw(size, space, OLD_DATA_SPACE); |
| 2336 if (result->IsFailure()) return result; | 2339 if (result->IsFailure()) return result; |
| 2337 | 2340 |
| 2338 reinterpret_cast<ByteArray*>(result)->set_map(THIS->byte_array_map()); | 2341 reinterpret_cast<ByteArray*>(result)->set_map(byte_array_map()); |
| 2339 reinterpret_cast<ByteArray*>(result)->set_length(length); | 2342 reinterpret_cast<ByteArray*>(result)->set_length(length); |
| 2340 return result; | 2343 return result; |
| 2341 } | 2344 } |
| 2342 | 2345 |
| 2343 | 2346 |
| 2344 void Heap::CreateFillerObjectAt(Address addr, int size) { | 2347 void Heap::CreateFillerObjectAt(Address addr, int size) { |
| 2345 if (size == 0) return; | 2348 if (size == 0) return; |
| 2346 HeapObject* filler = HeapObject::FromAddress(addr); | 2349 HeapObject* filler = HeapObject::FromAddress(addr); |
| 2347 if (size == kPointerSize) { | 2350 if (size == kPointerSize) { |
| 2348 filler->set_map(THIS->one_pointer_filler_map()); | 2351 filler->set_map(one_pointer_filler_map()); |
| 2349 } else if (size == 2 * kPointerSize) { | 2352 } else if (size == 2 * kPointerSize) { |
| 2350 filler->set_map(THIS->two_pointer_filler_map()); | 2353 filler->set_map(two_pointer_filler_map()); |
| 2351 } else { | 2354 } else { |
| 2352 filler->set_map(THIS->byte_array_map()); | 2355 filler->set_map(byte_array_map()); |
| 2353 ByteArray::cast(filler)->set_length(ByteArray::LengthFor(size)); | 2356 ByteArray::cast(filler)->set_length(ByteArray::LengthFor(size)); |
| 2354 } | 2357 } |
| 2355 } | 2358 } |
| 2356 | 2359 |
| 2357 | 2360 |
| 2358 Object* Heap::AllocatePixelArray(int length, | 2361 Object* Heap::AllocatePixelArray(int length, |
| 2359 uint8_t* external_pointer, | 2362 uint8_t* external_pointer, |
| 2360 PretenureFlag pretenure) { | 2363 PretenureFlag pretenure) { |
| 2361 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2364 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 2362 Object* result = AllocateRaw(PixelArray::kAlignedSize, space, OLD_DATA_SPACE); | 2365 Object* result = AllocateRaw(PixelArray::kAlignedSize, space, OLD_DATA_SPACE); |
| 2363 if (result->IsFailure()) return result; | 2366 if (result->IsFailure()) return result; |
| 2364 | 2367 |
| 2365 reinterpret_cast<PixelArray*>(result)->set_map(THIS->pixel_array_map()); | 2368 reinterpret_cast<PixelArray*>(result)->set_map(pixel_array_map()); |
| 2366 reinterpret_cast<PixelArray*>(result)->set_length(length); | 2369 reinterpret_cast<PixelArray*>(result)->set_length(length); |
| 2367 reinterpret_cast<PixelArray*>(result)->set_external_pointer(external_pointer); | 2370 reinterpret_cast<PixelArray*>(result)->set_external_pointer(external_pointer); |
| 2368 | 2371 |
| 2369 return result; | 2372 return result; |
| 2370 } | 2373 } |
| 2371 | 2374 |
| 2372 | 2375 |
| 2373 Object* Heap::AllocateExternalArray(int length, | 2376 Object* Heap::AllocateExternalArray(int length, |
| 2374 ExternalArrayType array_type, | 2377 ExternalArrayType array_type, |
| 2375 void* external_pointer, | 2378 void* external_pointer, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2488 Object* result; | 2491 Object* result; |
| 2489 if (obj_size > MaxObjectSizeInPagedSpace()) { | 2492 if (obj_size > MaxObjectSizeInPagedSpace()) { |
| 2490 result = lo_space_->AllocateRawCode(obj_size); | 2493 result = lo_space_->AllocateRawCode(obj_size); |
| 2491 } else { | 2494 } else { |
| 2492 result = code_space_->AllocateRaw(obj_size); | 2495 result = code_space_->AllocateRaw(obj_size); |
| 2493 } | 2496 } |
| 2494 | 2497 |
| 2495 if (result->IsFailure()) return result; | 2498 if (result->IsFailure()) return result; |
| 2496 | 2499 |
| 2497 // Initialize the object | 2500 // Initialize the object |
| 2498 HeapObject::cast(result)->set_map(THIS->code_map()); | 2501 HeapObject::cast(result)->set_map(code_map()); |
| 2499 Code* code = Code::cast(result); | 2502 Code* code = Code::cast(result); |
| 2500 ASSERT(!isolate_->code_range()->exists() || | 2503 ASSERT(!isolate_->code_range()->exists() || |
| 2501 isolate_->code_range()->contains(code->address())); | 2504 isolate_->code_range()->contains(code->address())); |
| 2502 code->set_instruction_size(desc.instr_size); | 2505 code->set_instruction_size(desc.instr_size); |
| 2503 code->set_relocation_info(ByteArray::cast(reloc_info)); | 2506 code->set_relocation_info(ByteArray::cast(reloc_info)); |
| 2504 code->set_flags(flags); | 2507 code->set_flags(flags); |
| 2505 // Allow self references to created code object by patching the handle to | 2508 // Allow self references to created code object by patching the handle to |
| 2506 // point to the newly allocated Code object. | 2509 // point to the newly allocated Code object. |
| 2507 if (!self_reference.is_null()) { | 2510 if (!self_reference.is_null()) { |
| 2508 *(self_reference.location()) = code; | 2511 *(self_reference.location()) = code; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2613 | 2616 |
| 2614 | 2617 |
| 2615 Object* Heap::InitializeFunction(JSFunction* function, | 2618 Object* Heap::InitializeFunction(JSFunction* function, |
| 2616 SharedFunctionInfo* shared, | 2619 SharedFunctionInfo* shared, |
| 2617 Object* prototype) { | 2620 Object* prototype) { |
| 2618 ASSERT(!prototype->IsMap()); | 2621 ASSERT(!prototype->IsMap()); |
| 2619 function->initialize_properties(); | 2622 function->initialize_properties(); |
| 2620 function->initialize_elements(); | 2623 function->initialize_elements(); |
| 2621 function->set_shared(shared); | 2624 function->set_shared(shared); |
| 2622 function->set_prototype_or_initial_map(prototype); | 2625 function->set_prototype_or_initial_map(prototype); |
| 2623 function->set_context(THIS->undefined_value()); | 2626 function->set_context(undefined_value()); |
| 2624 function->set_literals(THIS->empty_fixed_array()); | 2627 function->set_literals(empty_fixed_array()); |
| 2625 return function; | 2628 return function; |
| 2626 } | 2629 } |
| 2627 | 2630 |
| 2628 | 2631 |
| 2629 Object* Heap::AllocateFunctionPrototype(JSFunction* function) { | 2632 Object* Heap::AllocateFunctionPrototype(JSFunction* function) { |
| 2630 // Allocate the prototype. Make sure to use the object function | 2633 // Allocate the prototype. Make sure to use the object function |
| 2631 // from the function's context, since the function can be from a | 2634 // from the function's context, since the function can be from a |
| 2632 // different context. | 2635 // different context. |
| 2633 JSFunction* object_function = | 2636 JSFunction* object_function = |
| 2634 function->context()->global_context()->object_function(); | 2637 function->context()->global_context()->object_function(); |
| 2635 Object* prototype = AllocateJSObject(object_function); | 2638 Object* prototype = AllocateJSObject(object_function); |
| 2636 if (prototype->IsFailure()) return prototype; | 2639 if (prototype->IsFailure()) return prototype; |
| 2637 // When creating the prototype for the function we must set its | 2640 // When creating the prototype for the function we must set its |
| 2638 // constructor to the function. | 2641 // constructor to the function. |
| 2639 Object* result = | 2642 Object* result = |
| 2640 JSObject::cast(prototype)->SetProperty(THIS->constructor_symbol(), | 2643 JSObject::cast(prototype)->SetProperty(constructor_symbol(), |
| 2641 function, | 2644 function, |
| 2642 DONT_ENUM); | 2645 DONT_ENUM); |
| 2643 if (result->IsFailure()) return result; | 2646 if (result->IsFailure()) return result; |
| 2644 return prototype; | 2647 return prototype; |
| 2645 } | 2648 } |
| 2646 | 2649 |
| 2647 | 2650 |
| 2648 Object* Heap::AllocateFunction(Map* function_map, | 2651 Object* Heap::AllocateFunction(Map* function_map, |
| 2649 SharedFunctionInfo* shared, | 2652 SharedFunctionInfo* shared, |
| 2650 Object* prototype, | 2653 Object* prototype, |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3049 return result; | 3052 return result; |
| 3050 } | 3053 } |
| 3051 | 3054 |
| 3052 | 3055 |
| 3053 Map* Heap::SymbolMapForString(String* string) { | 3056 Map* Heap::SymbolMapForString(String* string) { |
| 3054 // If the string is in new space it cannot be used as a symbol. | 3057 // If the string is in new space it cannot be used as a symbol. |
| 3055 if (InNewSpace(string)) return NULL; | 3058 if (InNewSpace(string)) return NULL; |
| 3056 | 3059 |
| 3057 // Find the corresponding symbol map for strings. | 3060 // Find the corresponding symbol map for strings. |
| 3058 Map* map = string->map(); | 3061 Map* map = string->map(); |
| 3059 if (map == THIS->ascii_string_map()) { | 3062 if (map == ascii_string_map()) { |
| 3060 return THIS->ascii_symbol_map(); | 3063 return ascii_symbol_map(); |
| 3061 } | 3064 } |
| 3062 if (map == THIS->string_map()) { | 3065 if (map == string_map()) { |
| 3063 return THIS->symbol_map(); | 3066 return symbol_map(); |
| 3064 } | 3067 } |
| 3065 if (map == THIS->cons_string_map()) { | 3068 if (map == cons_string_map()) { |
| 3066 return THIS->cons_symbol_map(); | 3069 return cons_symbol_map(); |
| 3067 } | 3070 } |
| 3068 if (map == THIS->cons_ascii_string_map()) { | 3071 if (map == cons_ascii_string_map()) { |
| 3069 return THIS->cons_ascii_symbol_map(); | 3072 return cons_ascii_symbol_map(); |
| 3070 } | 3073 } |
| 3071 if (map == THIS->external_string_map()) { | 3074 if (map == external_string_map()) { |
| 3072 return THIS->external_symbol_map(); | 3075 return external_symbol_map(); |
| 3073 } | 3076 } |
| 3074 if (map == THIS->external_ascii_string_map()) { | 3077 if (map == external_ascii_string_map()) { |
| 3075 return THIS->external_ascii_symbol_map(); | 3078 return external_ascii_symbol_map(); |
| 3076 } | 3079 } |
| 3077 if (map == external_string_with_ascii_data_map()) { | 3080 if (map == external_string_with_ascii_data_map()) { |
| 3078 return external_symbol_with_ascii_data_map(); | 3081 return external_symbol_with_ascii_data_map(); |
| 3079 } | 3082 } |
| 3080 | 3083 |
| 3081 // No match found. | 3084 // No match found. |
| 3082 return NULL; | 3085 return NULL; |
| 3083 } | 3086 } |
| 3084 | 3087 |
| 3085 | 3088 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3100 buffer->Rewind(); | 3103 buffer->Rewind(); |
| 3101 | 3104 |
| 3102 // Compute map and object size. | 3105 // Compute map and object size. |
| 3103 int size; | 3106 int size; |
| 3104 Map* map; | 3107 Map* map; |
| 3105 | 3108 |
| 3106 if (is_ascii) { | 3109 if (is_ascii) { |
| 3107 if (chars > SeqAsciiString::kMaxLength) { | 3110 if (chars > SeqAsciiString::kMaxLength) { |
| 3108 return Failure::OutOfMemoryException(); | 3111 return Failure::OutOfMemoryException(); |
| 3109 } | 3112 } |
| 3110 map = THIS->ascii_symbol_map(); | 3113 map = ascii_symbol_map(); |
| 3111 size = SeqAsciiString::SizeFor(chars); | 3114 size = SeqAsciiString::SizeFor(chars); |
| 3112 } else { | 3115 } else { |
| 3113 if (chars > SeqTwoByteString::kMaxLength) { | 3116 if (chars > SeqTwoByteString::kMaxLength) { |
| 3114 return Failure::OutOfMemoryException(); | 3117 return Failure::OutOfMemoryException(); |
| 3115 } | 3118 } |
| 3116 map = THIS->symbol_map(); | 3119 map = symbol_map(); |
| 3117 size = SeqTwoByteString::SizeFor(chars); | 3120 size = SeqTwoByteString::SizeFor(chars); |
| 3118 } | 3121 } |
| 3119 | 3122 |
| 3120 // Allocate string. | 3123 // Allocate string. |
| 3121 Object* result = (size > MaxObjectSizeInPagedSpace()) | 3124 Object* result = (size > MaxObjectSizeInPagedSpace()) |
| 3122 ? lo_space_->AllocateRaw(size) | 3125 ? lo_space_->AllocateRaw(size) |
| 3123 : old_data_space_->AllocateRaw(size); | 3126 : old_data_space_->AllocateRaw(size); |
| 3124 if (result->IsFailure()) return result; | 3127 if (result->IsFailure()) return result; |
| 3125 | 3128 |
| 3126 reinterpret_cast<HeapObject*>(result)->set_map(map); | 3129 reinterpret_cast<HeapObject*>(result)->set_map(map); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3158 // Allocate in new space, retry in large object space. | 3161 // Allocate in new space, retry in large object space. |
| 3159 retry_space = LO_SPACE; | 3162 retry_space = LO_SPACE; |
| 3160 } | 3163 } |
| 3161 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { | 3164 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { |
| 3162 space = LO_SPACE; | 3165 space = LO_SPACE; |
| 3163 } | 3166 } |
| 3164 Object* result = AllocateRaw(size, space, retry_space); | 3167 Object* result = AllocateRaw(size, space, retry_space); |
| 3165 if (result->IsFailure()) return result; | 3168 if (result->IsFailure()) return result; |
| 3166 | 3169 |
| 3167 // Partially initialize the object. | 3170 // Partially initialize the object. |
| 3168 HeapObject::cast(result)->set_map(THIS->ascii_string_map()); | 3171 HeapObject::cast(result)->set_map(ascii_string_map()); |
| 3169 String::cast(result)->set_length(length); | 3172 String::cast(result)->set_length(length); |
| 3170 String::cast(result)->set_hash_field(String::kEmptyHashField); | 3173 String::cast(result)->set_hash_field(String::kEmptyHashField); |
| 3171 ASSERT_EQ(size, HeapObject::cast(result)->Size()); | 3174 ASSERT_EQ(size, HeapObject::cast(result)->Size()); |
| 3172 return result; | 3175 return result; |
| 3173 } | 3176 } |
| 3174 | 3177 |
| 3175 | 3178 |
| 3176 Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) { | 3179 Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) { |
| 3177 if (length < 0 || length > SeqTwoByteString::kMaxLength) { | 3180 if (length < 0 || length > SeqTwoByteString::kMaxLength) { |
| 3178 return Failure::OutOfMemoryException(); | 3181 return Failure::OutOfMemoryException(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3190 // Allocate in new space, retry in large object space. | 3193 // Allocate in new space, retry in large object space. |
| 3191 retry_space = LO_SPACE; | 3194 retry_space = LO_SPACE; |
| 3192 } | 3195 } |
| 3193 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { | 3196 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { |
| 3194 space = LO_SPACE; | 3197 space = LO_SPACE; |
| 3195 } | 3198 } |
| 3196 Object* result = AllocateRaw(size, space, retry_space); | 3199 Object* result = AllocateRaw(size, space, retry_space); |
| 3197 if (result->IsFailure()) return result; | 3200 if (result->IsFailure()) return result; |
| 3198 | 3201 |
| 3199 // Partially initialize the object. | 3202 // Partially initialize the object. |
| 3200 HeapObject::cast(result)->set_map(THIS->string_map()); | 3203 HeapObject::cast(result)->set_map(string_map()); |
| 3201 String::cast(result)->set_length(length); | 3204 String::cast(result)->set_length(length); |
| 3202 String::cast(result)->set_hash_field(String::kEmptyHashField); | 3205 String::cast(result)->set_hash_field(String::kEmptyHashField); |
| 3203 ASSERT_EQ(size, HeapObject::cast(result)->Size()); | 3206 ASSERT_EQ(size, HeapObject::cast(result)->Size()); |
| 3204 return result; | 3207 return result; |
| 3205 } | 3208 } |
| 3206 | 3209 |
| 3207 | 3210 |
| 3208 Object* Heap::AllocateEmptyFixedArray() { | 3211 Object* Heap::AllocateEmptyFixedArray() { |
| 3209 int size = FixedArray::SizeFor(0); | 3212 int size = FixedArray::SizeFor(0); |
| 3210 Object* result = AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); | 3213 Object* result = AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); |
| 3211 if (result->IsFailure()) return result; | 3214 if (result->IsFailure()) return result; |
| 3212 // Initialize the object. | 3215 // Initialize the object. |
| 3213 reinterpret_cast<FixedArray*>(result)->set_map(THIS->fixed_array_map()); | 3216 reinterpret_cast<FixedArray*>(result)->set_map(fixed_array_map()); |
| 3214 reinterpret_cast<FixedArray*>(result)->set_length(0); | 3217 reinterpret_cast<FixedArray*>(result)->set_length(0); |
| 3215 return result; | 3218 return result; |
| 3216 } | 3219 } |
| 3217 | 3220 |
| 3218 | 3221 |
| 3219 Object* Heap::AllocateRawFixedArray(int length) { | 3222 Object* Heap::AllocateRawFixedArray(int length) { |
| 3220 if (length < 0 || length > FixedArray::kMaxLength) { | 3223 if (length < 0 || length > FixedArray::kMaxLength) { |
| 3221 return Failure::OutOfMemoryException(); | 3224 return Failure::OutOfMemoryException(); |
| 3222 } | 3225 } |
| 3223 // Use the general function if we're forced to always allocate. | 3226 // Use the general function if we're forced to always allocate. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3246 // Copy the content | 3249 // Copy the content |
| 3247 AssertNoAllocation no_gc; | 3250 AssertNoAllocation no_gc; |
| 3248 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 3251 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 3249 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); | 3252 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); |
| 3250 return result; | 3253 return result; |
| 3251 } | 3254 } |
| 3252 | 3255 |
| 3253 | 3256 |
| 3254 Object* Heap::AllocateFixedArray(int length) { | 3257 Object* Heap::AllocateFixedArray(int length) { |
| 3255 ASSERT(length >= 0); | 3258 ASSERT(length >= 0); |
| 3256 if (length == 0) return THIS->empty_fixed_array(); | 3259 if (length == 0) return empty_fixed_array(); |
| 3257 Object* result = AllocateRawFixedArray(length); | 3260 Object* result = AllocateRawFixedArray(length); |
| 3258 if (!result->IsFailure()) { | 3261 if (!result->IsFailure()) { |
| 3259 // Initialize header. | 3262 // Initialize header. |
| 3260 FixedArray* array = reinterpret_cast<FixedArray*>(result); | 3263 FixedArray* array = reinterpret_cast<FixedArray*>(result); |
| 3261 array->set_map(THIS->fixed_array_map()); | 3264 array->set_map(fixed_array_map()); |
| 3262 array->set_length(length); | 3265 array->set_length(length); |
| 3263 // Initialize body. | 3266 // Initialize body. |
| 3264 ASSERT(!InNewSpace(THIS->undefined_value())); | 3267 ASSERT(!InNewSpace(undefined_value())); |
| 3265 MemsetPointer(array->data_start(), THIS->undefined_value(), length); | 3268 MemsetPointer(array->data_start(), undefined_value(), length); |
| 3266 } | 3269 } |
| 3267 return result; | 3270 return result; |
| 3268 } | 3271 } |
| 3269 | 3272 |
| 3270 | 3273 |
| 3271 Object* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) { | 3274 Object* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) { |
| 3272 if (length < 0 || length > FixedArray::kMaxLength) { | 3275 if (length < 0 || length > FixedArray::kMaxLength) { |
| 3273 return Failure::OutOfMemoryException(); | 3276 return Failure::OutOfMemoryException(); |
| 3274 } | 3277 } |
| 3275 | 3278 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3331 | 3334 |
| 3332 reinterpret_cast<FixedArray*>(obj)->set_map(fixed_array_map()); | 3335 reinterpret_cast<FixedArray*>(obj)->set_map(fixed_array_map()); |
| 3333 FixedArray::cast(obj)->set_length(length); | 3336 FixedArray::cast(obj)->set_length(length); |
| 3334 return obj; | 3337 return obj; |
| 3335 } | 3338 } |
| 3336 | 3339 |
| 3337 | 3340 |
| 3338 Object* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { | 3341 Object* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { |
| 3339 Object* result = AllocateFixedArray(length, pretenure); | 3342 Object* result = AllocateFixedArray(length, pretenure); |
| 3340 if (result->IsFailure()) return result; | 3343 if (result->IsFailure()) return result; |
| 3341 reinterpret_cast<HeapObject*>(result)->set_map(THIS->hash_table_map()); | 3344 reinterpret_cast<HeapObject*>(result)->set_map(hash_table_map()); |
| 3342 ASSERT(result->IsHashTable()); | 3345 ASSERT(result->IsHashTable()); |
| 3343 return result; | 3346 return result; |
| 3344 } | 3347 } |
| 3345 | 3348 |
| 3346 | 3349 |
| 3347 Object* Heap::AllocateGlobalContext() { | 3350 Object* Heap::AllocateGlobalContext() { |
| 3348 Object* result = AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); | 3351 Object* result = AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); |
| 3349 if (result->IsFailure()) return result; | 3352 if (result->IsFailure()) return result; |
| 3350 Context* context = reinterpret_cast<Context*>(result); | 3353 Context* context = reinterpret_cast<Context*>(result); |
| 3351 context->set_map(THIS->global_context_map()); | 3354 context->set_map(global_context_map()); |
| 3352 ASSERT(context->IsGlobalContext()); | 3355 ASSERT(context->IsGlobalContext()); |
| 3353 ASSERT(result->IsContext()); | 3356 ASSERT(result->IsContext()); |
| 3354 return result; | 3357 return result; |
| 3355 } | 3358 } |
| 3356 | 3359 |
| 3357 | 3360 |
| 3358 Object* Heap::AllocateFunctionContext(int length, JSFunction* function) { | 3361 Object* Heap::AllocateFunctionContext(int length, JSFunction* function) { |
| 3359 ASSERT(length >= Context::MIN_CONTEXT_SLOTS); | 3362 ASSERT(length >= Context::MIN_CONTEXT_SLOTS); |
| 3360 Object* result = AllocateFixedArray(length); | 3363 Object* result = AllocateFixedArray(length); |
| 3361 if (result->IsFailure()) return result; | 3364 if (result->IsFailure()) return result; |
| 3362 Context* context = reinterpret_cast<Context*>(result); | 3365 Context* context = reinterpret_cast<Context*>(result); |
| 3363 context->set_map(THIS->context_map()); | 3366 context->set_map(context_map()); |
| 3364 context->set_closure(function); | 3367 context->set_closure(function); |
| 3365 context->set_fcontext(context); | 3368 context->set_fcontext(context); |
| 3366 context->set_previous(NULL); | 3369 context->set_previous(NULL); |
| 3367 context->set_extension(NULL); | 3370 context->set_extension(NULL); |
| 3368 context->set_global(function->context()->global()); | 3371 context->set_global(function->context()->global()); |
| 3369 ASSERT(!context->IsGlobalContext()); | 3372 ASSERT(!context->IsGlobalContext()); |
| 3370 ASSERT(context->is_function_context()); | 3373 ASSERT(context->is_function_context()); |
| 3371 ASSERT(result->IsContext()); | 3374 ASSERT(result->IsContext()); |
| 3372 return result; | 3375 return result; |
| 3373 } | 3376 } |
| 3374 | 3377 |
| 3375 | 3378 |
| 3376 Object* Heap::AllocateWithContext(Context* previous, | 3379 Object* Heap::AllocateWithContext(Context* previous, |
| 3377 JSObject* extension, | 3380 JSObject* extension, |
| 3378 bool is_catch_context) { | 3381 bool is_catch_context) { |
| 3379 Object* result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS); | 3382 Object* result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS); |
| 3380 if (result->IsFailure()) return result; | 3383 if (result->IsFailure()) return result; |
| 3381 Context* context = reinterpret_cast<Context*>(result); | 3384 Context* context = reinterpret_cast<Context*>(result); |
| 3382 context->set_map(is_catch_context ? THIS->catch_context_map() : | 3385 context->set_map(is_catch_context ? catch_context_map() : |
| 3383 THIS->context_map()); | 3386 context_map()); |
| 3384 context->set_closure(previous->closure()); | 3387 context->set_closure(previous->closure()); |
| 3385 context->set_fcontext(previous->fcontext()); | 3388 context->set_fcontext(previous->fcontext()); |
| 3386 context->set_previous(previous); | 3389 context->set_previous(previous); |
| 3387 context->set_extension(extension); | 3390 context->set_extension(extension); |
| 3388 context->set_global(previous->global()); | 3391 context->set_global(previous->global()); |
| 3389 ASSERT(!context->IsGlobalContext()); | 3392 ASSERT(!context->IsGlobalContext()); |
| 3390 ASSERT(!context->is_function_context()); | 3393 ASSERT(!context->is_function_context()); |
| 3391 ASSERT(result->IsContext()); | 3394 ASSERT(result->IsContext()); |
| 3392 return result; | 3395 return result; |
| 3393 } | 3396 } |
| 3394 | 3397 |
| 3395 | 3398 |
| 3396 Object* Heap::AllocateStruct(InstanceType type) { | 3399 Object* Heap::AllocateStruct(InstanceType type) { |
| 3397 Map* map; | 3400 Map* map; |
| 3398 switch (type) { | 3401 switch (type) { |
| 3399 #define MAKE_CASE(NAME, Name, name) \ | 3402 #define MAKE_CASE(NAME, Name, name) \ |
| 3400 case NAME##_TYPE: map = THIS->name##_map(); break; | 3403 case NAME##_TYPE: map = name##_map(); break; |
| 3401 STRUCT_LIST(MAKE_CASE) | 3404 STRUCT_LIST(MAKE_CASE) |
| 3402 #undef MAKE_CASE | 3405 #undef MAKE_CASE |
| 3403 default: | 3406 default: |
| 3404 UNREACHABLE(); | 3407 UNREACHABLE(); |
| 3405 return Failure::InternalError(); | 3408 return Failure::InternalError(); |
| 3406 } | 3409 } |
| 3407 int size = map->instance_size(); | 3410 int size = map->instance_size(); |
| 3408 AllocationSpace space = | 3411 AllocationSpace space = |
| 3409 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE; | 3412 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE; |
| 3410 Object* result = Allocate(map, space); | 3413 Object* result = Allocate(map, space); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3663 code_space_->Verify(&no_dirty_regions_visitor); | 3666 code_space_->Verify(&no_dirty_regions_visitor); |
| 3664 cell_space_->Verify(&no_dirty_regions_visitor); | 3667 cell_space_->Verify(&no_dirty_regions_visitor); |
| 3665 | 3668 |
| 3666 lo_space_->Verify(); | 3669 lo_space_->Verify(); |
| 3667 } | 3670 } |
| 3668 #endif // DEBUG | 3671 #endif // DEBUG |
| 3669 | 3672 |
| 3670 | 3673 |
| 3671 Object* Heap::LookupSymbol(Vector<const char> string) { | 3674 Object* Heap::LookupSymbol(Vector<const char> string) { |
| 3672 Object* symbol = NULL; | 3675 Object* symbol = NULL; |
| 3673 Object* new_table = THIS->symbol_table()->LookupSymbol(string, &symbol); | 3676 Object* new_table = symbol_table()->LookupSymbol(string, &symbol); |
| 3674 if (new_table->IsFailure()) return new_table; | 3677 if (new_table->IsFailure()) return new_table; |
| 3675 // Can't use set_symbol_table because SymbolTable::cast knows that | 3678 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 3676 // SymbolTable is a singleton and checks for identity. | 3679 // SymbolTable is a singleton and checks for identity. |
| 3677 roots_[kSymbolTableRootIndex] = new_table; | 3680 roots_[kSymbolTableRootIndex] = new_table; |
| 3678 ASSERT(symbol != NULL); | 3681 ASSERT(symbol != NULL); |
| 3679 return symbol; | 3682 return symbol; |
| 3680 } | 3683 } |
| 3681 | 3684 |
| 3682 | 3685 |
| 3683 Object* Heap::LookupSymbol(String* string) { | 3686 Object* Heap::LookupSymbol(String* string) { |
| 3684 if (string->IsSymbol()) return string; | 3687 if (string->IsSymbol()) return string; |
| 3685 Object* symbol = NULL; | 3688 Object* symbol = NULL; |
| 3686 Object* new_table = THIS->symbol_table()->LookupString(string, &symbol); | 3689 Object* new_table = symbol_table()->LookupString(string, &symbol); |
| 3687 if (new_table->IsFailure()) return new_table; | 3690 if (new_table->IsFailure()) return new_table; |
| 3688 // Can't use set_symbol_table because SymbolTable::cast knows that | 3691 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 3689 // SymbolTable is a singleton and checks for identity. | 3692 // SymbolTable is a singleton and checks for identity. |
| 3690 roots_[kSymbolTableRootIndex] = new_table; | 3693 roots_[kSymbolTableRootIndex] = new_table; |
| 3691 ASSERT(symbol != NULL); | 3694 ASSERT(symbol != NULL); |
| 3692 return symbol; | 3695 return symbol; |
| 3693 } | 3696 } |
| 3694 | 3697 |
| 3695 | 3698 |
| 3696 bool Heap::LookupSymbolIfExists(String* string, String** symbol) { | 3699 bool Heap::LookupSymbolIfExists(String* string, String** symbol) { |
| 3697 if (string->IsSymbol()) { | 3700 if (string->IsSymbol()) { |
| 3698 *symbol = string; | 3701 *symbol = string; |
| 3699 return true; | 3702 return true; |
| 3700 } | 3703 } |
| 3701 return THIS->symbol_table()->LookupSymbolIfExists(string, symbol); | 3704 return symbol_table()->LookupSymbolIfExists(string, symbol); |
| 3702 } | 3705 } |
| 3703 | 3706 |
| 3704 | 3707 |
| 3705 #ifdef DEBUG | 3708 #ifdef DEBUG |
| 3706 void Heap::ZapFromSpace() { | 3709 void Heap::ZapFromSpace() { |
| 3707 ASSERT(reinterpret_cast<Object*>(kFromSpaceZapValue)->IsHeapObject()); | 3710 ASSERT(reinterpret_cast<Object*>(kFromSpaceZapValue)->IsHeapObject()); |
| 3708 for (Address a = new_space_.FromSpaceLow(); | 3711 for (Address a = new_space_.FromSpaceLow(); |
| 3709 a < new_space_.FromSpaceHigh(); | 3712 a < new_space_.FromSpaceHigh(); |
| 3710 a += kPointerSize) { | 3713 a += kPointerSize) { |
| 3711 Memory::Address_at(a) = kFromSpaceZapValue; | 3714 Memory::Address_at(a) = kFromSpaceZapValue; |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4675 | 4678 |
| 4676 // The large object code space may contain code or data. We set the memory | 4679 // The large object code space may contain code or data. We set the memory |
| 4677 // to be non-executable here for safety, but this means we need to enable it | 4680 // to be non-executable here for safety, but this means we need to enable it |
| 4678 // explicitly when allocating large code objects. | 4681 // explicitly when allocating large code objects. |
| 4679 lo_space_ = new LargeObjectSpace(LO_SPACE); | 4682 lo_space_ = new LargeObjectSpace(LO_SPACE); |
| 4680 if (lo_space_ == NULL) return false; | 4683 if (lo_space_ == NULL) return false; |
| 4681 if (!lo_space_->Setup()) return false; | 4684 if (!lo_space_->Setup()) return false; |
| 4682 | 4685 |
| 4683 if (create_heap_objects) { | 4686 if (create_heap_objects) { |
| 4684 // Create initial maps. | 4687 // Create initial maps. |
| 4685 if (!THIS->CreateInitialMaps()) return false; | 4688 if (!CreateInitialMaps()) return false; |
| 4686 if (!THIS->CreateApiObjects()) return false; | 4689 if (!CreateApiObjects()) return false; |
| 4687 | 4690 |
| 4688 // Create initial objects | 4691 // Create initial objects |
| 4689 if (!THIS->CreateInitialObjects()) return false; | 4692 if (!CreateInitialObjects()) return false; |
| 4690 } | 4693 } |
| 4691 | 4694 |
| 4692 LOG(IntEvent("heap-capacity", Capacity())); | 4695 LOG(IntEvent("heap-capacity", Capacity())); |
| 4693 LOG(IntEvent("heap-available", Available())); | 4696 LOG(IntEvent("heap-available", Available())); |
| 4694 | 4697 |
| 4695 #ifdef ENABLE_LOGGING_AND_PROFILING | 4698 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 4696 // This should be called only after initial objects have been created. | 4699 // This should be called only after initial objects have been created. |
| 4697 isolate_->producer_heap_profile()->Setup(); | 4700 isolate_->producer_heap_profile()->Setup(); |
| 4698 #endif | 4701 #endif |
| 4699 | 4702 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4965 delete caches_[i]; | 4968 delete caches_[i]; |
| 4966 caches_[i] = NULL; | 4969 caches_[i] = NULL; |
| 4967 } | 4970 } |
| 4968 } | 4971 } |
| 4969 } | 4972 } |
| 4970 | 4973 |
| 4971 | 4974 |
| 4972 void ExternalStringTable::CleanUp() { | 4975 void ExternalStringTable::CleanUp() { |
| 4973 int last = 0; | 4976 int last = 0; |
| 4974 for (int i = 0; i < new_space_strings_.length(); ++i) { | 4977 for (int i = 0; i < new_space_strings_.length(); ++i) { |
| 4975 if (new_space_strings_[i] == HEAP->raw_unchecked_null_value()) continue; | 4978 if (new_space_strings_[i] == heap_->raw_unchecked_null_value()) continue; |
| 4976 if (HEAP->InNewSpace(new_space_strings_[i])) { | 4979 if (heap_->InNewSpace(new_space_strings_[i])) { |
| 4977 new_space_strings_[last++] = new_space_strings_[i]; | 4980 new_space_strings_[last++] = new_space_strings_[i]; |
| 4978 } else { | 4981 } else { |
| 4979 old_space_strings_.Add(new_space_strings_[i]); | 4982 old_space_strings_.Add(new_space_strings_[i]); |
| 4980 } | 4983 } |
| 4981 } | 4984 } |
| 4982 new_space_strings_.Rewind(last); | 4985 new_space_strings_.Rewind(last); |
| 4983 last = 0; | 4986 last = 0; |
| 4984 for (int i = 0; i < old_space_strings_.length(); ++i) { | 4987 for (int i = 0; i < old_space_strings_.length(); ++i) { |
| 4985 if (old_space_strings_[i] == HEAP->raw_unchecked_null_value()) continue; | 4988 if (old_space_strings_[i] == heap_->raw_unchecked_null_value()) continue; |
| 4986 ASSERT(!HEAP->InNewSpace(old_space_strings_[i])); | 4989 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); |
| 4987 old_space_strings_[last++] = old_space_strings_[i]; | 4990 old_space_strings_[last++] = old_space_strings_[i]; |
| 4988 } | 4991 } |
| 4989 old_space_strings_.Rewind(last); | 4992 old_space_strings_.Rewind(last); |
| 4990 Verify(); | 4993 Verify(); |
| 4991 } | 4994 } |
| 4992 | 4995 |
| 4993 | 4996 |
| 4994 void ExternalStringTable::TearDown() { | 4997 void ExternalStringTable::TearDown() { |
| 4995 new_space_strings_.Free(); | 4998 new_space_strings_.Free(); |
| 4996 old_space_strings_.Free(); | 4999 old_space_strings_.Free(); |
| 4997 } | 5000 } |
| 4998 | 5001 |
| 4999 | 5002 |
| 5000 } } // namespace v8::internal | 5003 } } // namespace v8::internal |
| OLD | NEW |