• Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

1. Memory layout

Memory five areas

  • The stack: Stores local variables, parameters, Pointers, and functions. The address usually begins with 0x7. The memory in the stack area is located through the SP register.
  • The heap: Stores objects that alloc and new open up memory. The address usually begins with 0x6.
  • Global region (BSS): uninitialized global and static variables with addresses beginning with 0x1.
  • Constant area (data): initialized global and static variables. The address usually begins with 0x1.
  • Code area (text): mainly used to store the program running code, code will be compiled into binary memory

In addition to the five areas of memory, there are also the kernel area, which is used by the system for kernel processing operations, and the reserved area, which is reserved for the system to handle nil and so on. Oxc0000000 represents only three GIGABytes, that is, four gigabytes of memory, one GIGAByte allocated to the kernel.

2. Memory management solution

In addition to MRC and ARC, there are three memory management schemes

  • TaggedPointer: used to store Pointers to small objects such as NSNumber,NSDate, etc., Pointers also store tags and content, optimize memory and access speed.

WWDC about TaggedPointer

  • NONPOINTER_ISA: Non-pointer ISA
  • Hash table: reference count table, weak reference table

2.1 Simulator debugging TaggedPointer

Here we see that there are three types of NSString:

  • NSCFConstantString: is a string constantCompile-time constantThe retainCount value is so large that operating on it does not cause reference count changes and is stored inString constant area
  • NSCFString: it is inThe runtimeTo create theNsstrings subclass, the reference count is incremented by 1 and stored inThe heap
  • NSTaggedPointerString: label pointer, which is apple’s optimization of NSString, NSNumber and other objects in 64-bit environment. For NSString objects
    • When a string is created byNumbers and LettersCombination and lengthLess than or equal to 9, automatically becomesNSTaggedPointerStringType stored in the constant area
    • When you haveChinese or other special symbols, will directly become__NSCFStringType stored inThe heap area

reference

Next go to the source code and search for TaggedPointer. So if you see that there’s a position operation for playload, there’s some encryption and decryption going on. So let’s go search decode.

Here we see the _objc_decodeTaggedPointer method, _objc_decodeTaggedPointer also calls _objc_decodeTaggedPointer_noPermute to perform an xor operation on pointer.

Search for objc_debug_taggedpointer_obfuscator, see the initializeTaggedPointerObfuscator initialized. Here, if obfuscation is turned on, you get a random objC_debug_TaggedPOinter_obfuscator value, otherwise 0.

And when you see encode here it’s also xor objC_debug_taggedPOinter_obfuscator, so you get the original value by xor twice.

The move left and move right operation is inside _objc_makeTaggedPointer. You can see here that we move first, we encrypt.

Next print the address of NSTaggedPointerString and move it three places to the right to remove the tag. Since it is in small-endian mode, read from back to front, reading 107 and 99 for k and C respectively.

NSTaggedPointerString address 1 indicates that the pointer is a Target pointer, and then 010, which is 2, represents an NSString.

So if it’s NSNumber, it’s 011, which is 3.

2.2 Real machine debugging TaggedPointer

So here we see that we’re just marking this one as TaggedPointer and it’s kind of running to the end. And then we have 0010 in front of it, which is 2. What is this? Does it stand for character length?

You see here asD and ASDF are printed as 0011 and 0100, respectively, for 3 and 4. Here it is stated that it does represent the character length.

So what does this stand for in NSNumber? Here we see that the value of 6 is 2 and the value of 6.0 is 5. Does it represent a type? After some experimentation, char is 0, short is 1, int is 2, long is 3, float is 4, and double is 5.