| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 virtual void Print() = 0; | 308 virtual void Print() = 0; |
| 309 #endif | 309 #endif |
| 310 | 310 |
| 311 private: | 311 private: |
| 312 AllocationSpace id_; | 312 AllocationSpace id_; |
| 313 Executability executable_; | 313 Executability executable_; |
| 314 }; | 314 }; |
| 315 | 315 |
| 316 | 316 |
| 317 // ---------------------------------------------------------------------------- | 317 // ---------------------------------------------------------------------------- |
| 318 // All heap objects containing executable code (code objects) must be allocated | |
| 319 // from a 2 GB range of memory, so that they can call each other using 32-bit | |
| 320 // displacements. This happens automatically on 32-bit platforms, where 32-bit | |
| 321 // displacements cover the entire 4GB virtual address space. On 64-bit | |
| 322 // platforms, we support this using the CodeRange object, which reserves and | |
| 323 // manages a range of virtual memory. | |
| 324 class CodeRange : public AllStatic { | |
| 325 public: | |
| 326 // Reserves a range of virtual memory, but does not commit any of it. | |
| 327 // Can only be called once, at heap initialization time. | |
| 328 // Returns false on failure. | |
| 329 static bool Setup(const size_t requested_size); | |
| 330 | |
| 331 // Frees the range of virtual memory, and frees the data structures used to | |
| 332 // manage it. | |
| 333 static void TearDown(); | |
| 334 | |
| 335 static bool exists() { return code_range_ != NULL; } | |
| 336 static bool contains(Address address) { | |
| 337 if (code_range_ == NULL) return false; | |
| 338 Address start = static_cast<Address>(code_range_->address()); | |
| 339 return start <= address && address < start + code_range_->size(); | |
| 340 } | |
| 341 | |
| 342 // Allocates a chunk of memory from the large-object portion of | |
| 343 // the code range. On platforms with no separate code range, should | |
| 344 // not be called. | |
| 345 static void* AllocateRawMemory(const size_t requested, size_t* allocated); | |
| 346 static void FreeRawMemory(void* buf, size_t length); | |
| 347 | |
| 348 private: | |
| 349 // The reserved range of virtual memory that all code objects are put in. | |
| 350 static VirtualMemory* code_range_; | |
| 351 // Plain old data class, just a struct plus a constructor. | |
| 352 class FreeBlock { | |
| 353 public: | |
| 354 FreeBlock(Address start_arg, size_t size_arg) | |
| 355 : start(start_arg), size(size_arg) {} | |
| 356 FreeBlock(void* start_arg, size_t size_arg) | |
| 357 : start(static_cast<Address>(start_arg)), size(size_arg) {} | |
| 358 | |
| 359 Address start; | |
| 360 size_t size; | |
| 361 }; | |
| 362 | |
| 363 // Freed blocks of memory are added to the free list. When the allocation | |
| 364 // list is exhausted, the free list is sorted and merged to make the new | |
| 365 // allocation list. | |
| 366 static List<FreeBlock> free_list_; | |
| 367 // Memory is allocated from the free blocks on the allocation list. | |
| 368 // The block at current_allocation_block_index_ is the current block. | |
| 369 static List<FreeBlock> allocation_list_; | |
| 370 static int current_allocation_block_index_; | |
| 371 | |
| 372 // Finds a block on the allocation list that contains at least the | |
| 373 // requested amount of memory. If none is found, sorts and merges | |
| 374 // the existing free memory blocks, and searches again. | |
| 375 // If none can be found, terminates V8 with FatalProcessOutOfMemory. | |
| 376 static void GetNextAllocationBlock(size_t requested); | |
| 377 // Compares the start addresses of two free blocks. | |
| 378 static int CompareFreeBlockAddress(const FreeBlock* left, | |
| 379 const FreeBlock* right); | |
| 380 }; | |
| 381 | |
| 382 | |
| 383 // ---------------------------------------------------------------------------- | |
| 384 // A space acquires chunks of memory from the operating system. The memory | 318 // A space acquires chunks of memory from the operating system. The memory |
| 385 // allocator manages chunks for the paged heap spaces (old space and map | 319 // allocator manages chunks for the paged heap spaces (old space and map |
| 386 // space). A paged chunk consists of pages. Pages in a chunk have contiguous | 320 // space). A paged chunk consists of pages. Pages in a chunk have contiguous |
| 387 // addresses and are linked as a list. | 321 // addresses and are linked as a list. |
| 388 // | 322 // |
| 389 // The allocator keeps an initial chunk which is used for the new space. The | 323 // The allocator keeps an initial chunk which is used for the new space. The |
| 390 // leftover regions of the initial chunk are used for the initial chunks of | 324 // leftover regions of the initial chunk are used for the initial chunks of |
| 391 // old space and map space if they are big enough to hold at least one page. | 325 // old space and map space if they are big enough to hold at least one page. |
| 392 // The allocator assumes that there is one old space and one map space, each | 326 // The allocator assumes that there is one old space and one map space, each |
| 393 // expands the space by allocating kPagesPerChunk pages except the last | 327 // expands the space by allocating kPagesPerChunk pages except the last |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 // block is contained in the initial chunk. Returns true if it succeeded | 373 // block is contained in the initial chunk. Returns true if it succeeded |
| 440 // and false otherwise. | 374 // and false otherwise. |
| 441 static bool UncommitBlock(Address start, size_t size); | 375 static bool UncommitBlock(Address start, size_t size); |
| 442 | 376 |
| 443 // Attempts to allocate the requested (non-zero) number of pages from the | 377 // Attempts to allocate the requested (non-zero) number of pages from the |
| 444 // OS. Fewer pages might be allocated than requested. If it fails to | 378 // OS. Fewer pages might be allocated than requested. If it fails to |
| 445 // allocate memory for the OS or cannot allocate a single page, this | 379 // allocate memory for the OS or cannot allocate a single page, this |
| 446 // function returns an invalid page pointer (NULL). The caller must check | 380 // function returns an invalid page pointer (NULL). The caller must check |
| 447 // whether the returned page is valid (by calling Page::is_valid()). It is | 381 // whether the returned page is valid (by calling Page::is_valid()). It is |
| 448 // guaranteed that allocated pages have contiguous addresses. The actual | 382 // guaranteed that allocated pages have contiguous addresses. The actual |
| 449 // number of allocated pages is returned in the output parameter | 383 // number of allocated page is returned in the output parameter |
| 450 // allocated_pages. If the PagedSpace owner is executable and there is | 384 // allocated_pages. |
| 451 // a code range, the pages are allocated from the code range. | |
| 452 static Page* AllocatePages(int requested_pages, int* allocated_pages, | 385 static Page* AllocatePages(int requested_pages, int* allocated_pages, |
| 453 PagedSpace* owner); | 386 PagedSpace* owner); |
| 454 | 387 |
| 455 // Frees pages from a given page and after. If 'p' is the first page | 388 // Frees pages from a given page and after. If 'p' is the first page |
| 456 // of a chunk, pages from 'p' are freed and this function returns an | 389 // of a chunk, pages from 'p' are freed and this function returns an |
| 457 // invalid page pointer. Otherwise, the function searches a page | 390 // invalid page pointer. Otherwise, the function searches a page |
| 458 // after 'p' that is the first page of a chunk. Pages after the | 391 // after 'p' that is the first page of a chunk. Pages after the |
| 459 // found page are freed and the function returns 'p'. | 392 // found page are freed and the function returns 'p'. |
| 460 static Page* FreePages(Page* p); | 393 static Page* FreePages(Page* p); |
| 461 | 394 |
| 462 // Allocates and frees raw memory of certain size. | 395 // Allocates and frees raw memory of certain size. |
| 463 // These are just thin wrappers around OS::Allocate and OS::Free, | 396 // These are just thin wrappers around OS::Allocate and OS::Free, |
| 464 // but keep track of allocated bytes as part of heap. | 397 // but keep track of allocated bytes as part of heap. |
| 465 // If the flag is EXECUTABLE and a code range exists, the requested | |
| 466 // memory is allocated from the code range. If a code range exists | |
| 467 // and the freed memory is in it, the code range manages the freed memory. | |
| 468 static void* AllocateRawMemory(const size_t requested, | 398 static void* AllocateRawMemory(const size_t requested, |
| 469 size_t* allocated, | 399 size_t* allocated, |
| 470 Executability executable); | 400 Executability executable); |
| 471 static void FreeRawMemory(void* buf, size_t length); | 401 static void FreeRawMemory(void* buf, size_t length); |
| 472 | 402 |
| 473 // Returns the maximum available bytes of heaps. | 403 // Returns the maximum available bytes of heaps. |
| 474 static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } | 404 static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } |
| 475 | 405 |
| 476 // Returns allocated spaces in bytes. | 406 // Returns allocated spaces in bytes. |
| 477 static int Size() { return size_; } | 407 static int Size() { return size_; } |
| (...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 | 1863 |
| 1934 private: | 1864 private: |
| 1935 LargeObjectChunk* current_; | 1865 LargeObjectChunk* current_; |
| 1936 HeapObjectCallback size_func_; | 1866 HeapObjectCallback size_func_; |
| 1937 }; | 1867 }; |
| 1938 | 1868 |
| 1939 | 1869 |
| 1940 } } // namespace v8::internal | 1870 } } // namespace v8::internal |
| 1941 | 1871 |
| 1942 #endif // V8_SPACES_H_ | 1872 #endif // V8_SPACES_H_ |
| OLD | NEW |