In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how to achieve js engine SemiSpace", the content of the article is simple and clear, easy to learn and understand, now please follow the editor's ideas slowly in depth, together to study and learn "how to achieve js engine SemiSpace"!
1 SemiSpace
SemiSpace is a class that manages a new generation of memory.
/ / SemiSpace in young generation
/ /
/ / A semispace is a contiguous chunk of memory. The mark-compact collector
/ / uses the memory in the from space as a marking stack when tracing live
/ / objects.
Class SemiSpace BASE_EMBEDDED {
Public:
/ / Creates a space in the young generation. The constructor does not
/ / allocate memory from the OS. A SemiSpace is given a contiguous chunk of
/ / memory of size 'capacity' when set up, and does not grow or shrink
/ / otherwise. In the mark-compact collector, the memory region of the from
/ / space is used as the marking stack. It requires contiguous memory
/ / addresses.
SemiSpace (int initial_capacity, int maximum_capacity)
/ / Sets up the semispace using the given chunk.
Bool Setup (Address start, int size)
/ / Tear down the space. Heap memory was not allocated by the space, so it
/ / is not deallocated here.
Void TearDown ()
/ / True if the space has been set up but not torn down.
Bool HasBeenSetup () {return start_! = NULL;}
Bool Double ()
/ / Returns the start address of the space.
Address low () {return start_;}
/ / Returns one past the end address of the space.
Address high () {return low () + capacity_;}
/ / Age mark accessors.
Address age_mark () {return ag offset _ mark_;}
Void set_age_mark (Address mark) {age_mark_ = mark;}
/ / True if the address is in the address range of this semispace (not
/ / necessarily below the allocation pointer).
/ / to determine whether the address an is in the memory managed by the object, & address_mask subtracts the size of the size-1 from a. If it is equal to start, it is within the scope of management.
Bool Contains (Address a) {
Return (reinterpret_cast (a) & address_mask_)
= = reinterpret_cast (start_)
}
/ / True if the object is a heap object in the address range of this
/ / semispace (not necessarily below the allocation pointer).
/ / similar to the logic above, but the low order of the heap object is marked, which needs to be dealt with when judging, adding SetUp
Bool Contains (Object* o) {
Return (reinterpret_cast (o) & object_mask_) = = object_expected_
}
/ / The offset of an address from the begining of the space.
/ / p from the start address
Int SpaceOffsetForAddress (Address addr) {return addr-low ();}
Private:
/ / The current and maximum capacity of the space.
Int capacity_
Int maximum_capacity_
/ / The start address of the space.
Address start_
/ / Used to govern object promotion during mark-compact collection.
Address age_mark_
/ / Masks and comparison values to test for containment in this semispace.
/ / see SetUp function
Uint32_t address_ma function
Uint32_t object_mask_
Uint32_t object_expected_
Public:
TRACK_MEMORY ("SemiSpace")
}
The following is the implementation
SemiSpace::SemiSpace (int initial_capacity, int maximum_capacity)
Capacity_ (initial_capacity), maximum_capacity_ (maximum_capacity)
Start_ (NULL), age_mark_ (NULL) {
}
/ / set the address range for management
Bool SemiSpace::Setup (Address start, int size) {
ASSERT (size = = maximum_capacity_)
/ / determine the validity of the address
If (! MemoryAllocator::CommitBlock (start, capacity_)) return false
/ / manage the first address of the address space
Start_ = start
/ / A mask that is lower than the valid range, that is, to ensure that the corresponding value is less than or equal to the managed address range
Address_mask_ = ~ (size-1)
/ / calculate the address mask of the object. The low bit is the mark bit, which needs to be reserved when judging.
Object_mask_ = address_mask_ | kHeapObjectTag
/ / see contains function. The low bit in the object address is the mark bit, which needs to be taken when judging.
Object_expected_ = reinterpret_cast (start) | kHeapObjectTag
/ / related to gc
Age_mark_ = start_
Return true
}
Ja
Void SemiSpace::TearDown () {
Start_ = NULL
Capacity_ = 0
}
/ / expand capacity
Bool SemiSpace::Double () {
If (! MemoryAllocator::CommitBlock (high (), capacity_)) return false
Capacity_ * = 2
Return true
}
SemiSpace himself does not apply for memory. He is responsible for managing a piece of memory, and memory requests are processed elsewhere.
2 NewSpace
NewSpace is also the class that manages the new generation of memory. The new generation of memory is divided into two halves, one is the from area and the other is the to area. The specific role will be discussed in the analysis of gc.
/ / The young generation space.
/ /
/ / The new space consists of a contiguous pair of semispaces. It simply
/ / forwards most functions to the appropriate semispace.
Class NewSpace: public Malloced {
Public:
NewSpace (int initial_semispace_capacity, int maximum_semispace_capacity)
Bool Setup (Address start, int size)
Void TearDown ()
/ / True if the space has been set up but not torn down.
Bool HasBeenSetup () {
Return to_space_- > HasBeenSetup () & & from_space_- > HasBeenSetup ()
}
/ / Flip the pair of spaces.
Void Flip ()
Bool Double ()
Bool Contains (Address a) {
Return (reinterpret_cast (a) & address_mask_)
= = reinterpret_cast (start_)
}
Bool Contains (Object* o) {
Return (reinterpret_cast (o) & object_mask_) = = object_expected_
}
/ / Return the allocated bytes in the active semispace.
/ / amount of memory allocated in the to area
Int Size () {return top ()-bottom ();}
/ / Return the current capacity of a semispace.
Int Capacity () {return capacity_;}
/ / Return the available bytes without growing in the active semispace.
/ / how much memory is available in the to area
Int Available () {return Capacity ()-Size ();}
/ / Return the maximum capacity of a semispace.
Int MaximumCapacity () {return maximum_capacity_;}
/ / Return the address of the allocation pointer in the active semispace.
/ / the last address of the memory currently allocated
Address top () {return allocation_info_.top;}
/ / Return the address of the first object in thkeyoctive semispace.
/ / the first address of the managed memory of to_space
Address bottom () {return to_space_- > low ();}
/ / Get the age mark of the inactive semispace.
Address age_mark () {return from_space_- > age_mark ();}
/ / Set the age mark in the active semispace.
Void set_age_mark (Address mark) {to_space_- > set_age_mark (mark);}
/ / The start address of the space and a bit mask. Anding an address in the
/ / new space with the mask will result in the start address.
Address start () {return start_;}
Uint32_t mask () {return address_mask_;}
/ / The allocation top and limit addresses.
/ / the last address of the currently allocated memory
Address* allocation_top_address () {return & allocation_info_.top;}
/ / the last address of the memory that can be allocated at the maximum
Address* allocation_limit_address () {return & allocation_info_.limit;}
Object* AllocateRaw (int size_in_bytes) {
Return AllocateRawInternal (size_in_bytes, & allocation_info_)
}
Object* MCAllocateRaw (int size_in_bytes) {
Return AllocateRawInternal (size_in_bytes, & mc_forwarding_info_)
}
Void ResetAllocationInfo ()
Void MCResetRelocationInfo ()
Void MCCommitRelocationInfo ()
/ / Get the extent of the inactive semispace (for use as a marking stack).
Address FromSpaceLow () {return from_space_- > low ();}
Address FromSpaceHigh () {return from_space_- > high ();}
/ / Get the extent of the active semispace (to sweep newly copied objects
/ / during a scavenge collection).
Address ToSpaceLow () {return to_space_- > low ();}
Address ToSpaceHigh () {return to_space_- > high ();}
/ / Offsets from the beginning of the semispaces.
Int ToSpaceOffsetForAddress (Address a) {
Return to_space_- > SpaceOffsetForAddress (a)
}
Int FromSpaceOffsetForAddress (Address a) {
Return from_space_- > SpaceOffsetForAddress (a)
}
Bool ToSpaceContains (Object* o) {return to_space_- > Contains (o);}
Bool FromSpaceContains (Object* o) {return from_space_- > Contains (o);}
Bool ToSpaceContains (Address a) {return to_space_- > Contains (a);}
Bool FromSpaceContains (Address a) {return from_space_- > Contains (a);}
Void RecordAllocation (HeapObject* obj)
Void RecordPromotion (HeapObject* obj)
# endif
Private:
/ / The current and maximum capacities of a semispace.
Int capacity_
Int maximum_capacity_
/ / The semispaces.
SemiSpace* to_space_
SemiSpace* from_space_
/ / Start address and bit mask for containment testing.
Address start_
Uint32_t address_mask_
Uint32_t object_mask_
Uint32_t object_expected_
/ / Allocation pointer and limit for normal allocation and allocation during
/ / mark-compact collection.
AllocationInfo allocation_info_
AllocationInfo mc_forwarding_info_
/ / Implementation of AllocateRaw and MCAllocateRaw.
Inline Object* AllocateRawInternal (int size_in_bytes
AllocationInfo* alloc_info)
Friend class SemiSpaceIterator
Public:
TRACK_MEMORY ("NewSpace")
}
Many of the functions of newSpace can be achieved by semiSpace. He is responsible for the specific allocation of memory. But not responsible for memory application. There are also some functions related to gc, which will be analyzed later.
/ / divided into two space
NewSpace::NewSpace (int initial_semispace_capacity
Int maximum_semispace_capacity) {
ASSERT (initial_semispace_capacity Setup (start, maximum_capacity_)) {
Return false
}
/ / from area, half of each person in to area
If (from_space_ = = NULL
|! from_space_- > Setup (start + maximum_capacity_, maximum_capacity_)) {
Return false
}
/ / start address
Start_ = start
/ *
The high bit of address_mask is the significant bit of the address.
Size has only one, minus one, and then one becomes zero, one on the right.
All the zeros become 1, and then the high zero becomes 1, plus the original 1 in size
That is, the 1-bit address significant bit from left to right
, /
Address_mask_ = ~ (size-1)
/ / refer to the analysis of semiSpace
Object_mask_ = address_mask_ | kHeapObjectTag
Object_expected_ = reinterpret_cast (start) | kHeapObjectTag
/ / initialize the managed address information
Allocation_info_.top = to_space_- > low ()
Allocation_info_.limit = to_space_- > high ()
Mc_forwarding_info_.top = NULL
Mc_forwarding_info_.limit = NULL
ASSERT_SEMISPACE_ALLOCATION_INFO (allocation_info_, to_space_)
Return true
}
/ / reset properties, not responsible for memory release
Void NewSpace::TearDown () {
Start_ = NULL
Capacity_ = 0
Allocation_info_.top = NULL
Allocation_info_.limit = NULL
Mc_forwarding_info_.top = NULL
Mc_forwarding_info_.limit = NULL
If (to_space_! = NULL) {
To_space_- > TearDown ()
Delete to_space_
To_space_ = NULL
}
If (from_space_! = NULL) {
From_space_- > TearDown ()
Delete from_space_
From_space_ = NULL
}
}
/ / Flip, call in gc
Void NewSpace::Flip () {
SemiSpace* tmp = from_space_
From_space_ = to_space_
To_space_ = tmp
}
/ / expand capacity
Bool NewSpace::Double () {
ASSERT (capacity_ Double () | |! from_space_- > Double ()) return false
Capacity_ * = 2
/ / allocate memory from the address of the new expansion, that is, the end of the old memory.
Allocation_info_.limit = to_space_- > high ()
ASSERT_SEMISPACE_ALLOCATION_INFO (allocation_info_, to_space_)
Return true
}
/ / reset the pointer to manage memory allocation
Void NewSpace::ResetAllocationInfo () {
Allocation_info_.top = to_space_- > low ()
Allocation_info_.limit = to_space_- > high ()
ASSERT_SEMISPACE_ALLOCATION_INFO (allocation_info_, to_space_)
}
Void NewSpace::MCResetRelocationInfo () {
Mc_forwarding_info_.top = from_space_- > low ()
Mc_forwarding_info_.limit = from_space_- > high ()
ASSERT_SEMISPACE_ALLOCATION_INFO (mc_forwarding_info_, from_space_)
}
Void NewSpace::MCCommitRelocationInfo () {
/ / Assumes that the spaces have been flipped so that mc_forwarding_info_ is
/ / valid allocation info for the to space.
Allocation_info_.top = mc_forwarding_info_.top
Allocation_info_.limit = to_space_- > high ()
ASSERT_SEMISPACE_ALLOCATION_INFO (allocation_info_, to_space_)
}
We see that there is not a lot of specific logic in the implementation, just manipulating the properties, or sending the operations to semiSpace. Let's take a look at the function of memory allocation.
/ / allocate memory
Object* NewSpace::AllocateRawInternal (int size_in_bytes
AllocationInfo* alloc_info) {
Address new_top = alloc_info- > top + size_in_bytes
/ / not enough memory
If (new_top > alloc_info- > limit) {
Return Failure::RetryAfterGC (size_in_bytes, NEW_SPACE)
}
/ / address + lower bit mark
Object* obj = HeapObject::FromAddress (alloc_info- > top)
/ / Update the pointer to the next block of allocable memory
Alloc_info- > top = new_top
# ifdef DEBUG
SemiSpace* space =
(alloc_info = & allocation_info_)? To_space_: from_space_
ASSERT (space- > low () top
& & alloc_info- > top high ()
& & alloc_info- > limit = = space- > high ()
# endif
Return obj
}
}
Memory management is mainly managed through the start pointer, the end pointer, and the pointer to the currently allocated memory. Each time memory is allocated, the value of the current pointer is modified.
Thank you for your reading, the above is the content of "how to achieve js engine SemiSpace", after the study of this article, I believe you have a deeper understanding of how to achieve js engine SemiSpace, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.