Skip to content

Commit

Permalink
Organize snippets for "Optimization".
Browse files Browse the repository at this point in the history
  • Loading branch information
munificent committed Mar 19, 2020
1 parent 70563e2 commit 4e93be8
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 48 deletions.
169 changes: 151 additions & 18 deletions book/optimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ https://github.com/munificent/craftinginterpreters/issues/565

https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-representations.html

### unsorted
---

mention inlining small strings

---

...

^code define-nan-tagging (1 before, 1 after)
## modulo

...

Expand All @@ -42,67 +46,79 @@ https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-rep

...

^code free-table (1 before, 1 after)
### find entry

...

^code find-entry (1 before, 1 after)
^code find-entry

...

^code initial-index (1 before, 1 after)

...

^code next-index (1 before, 1 after)
^code next-index (4 before, 1 after)

...

^code get-find-entry (1 before, 1 after)
### adjust capacity

...

^code adjust-capacity (1 before, 1 after)
^code adjust-find-entry (2 before, 1 after)

...

^code re-hash (1 before, 1 after)
^code adjust-capacity (1 after)

...

^code adjust-find-entry (1 before, 1 after)
^code re-hash (1 before, 1 after)

...

^code adjust-free (1 before, 1 after)
^code adjust-free (3 before, 1 after)

...

^code adjust-set-capacity (1 before, 1 after)

...

^code table-set-grow (1 before, 1 after)
### table get set delete

...

^code get-find-entry (2 before, 1 after)

...

^code set-find-entry (3 before, 2 after)

...

^code set-find-entry (1 before, 1 after)
^code table-set-grow (1 before, 1 after)

...

^code delete-find-entry (1 before, 1 after)

...

### other changes

...

^code add-all-loop (1 before, 1 after)

...

^code find-string-index (1 before, 1 after)
^code find-string-index (4 before, 2 after)

...

^code find-string-next (1 before, 1 after)
^code find-string-next (3 before, 1 after)

...

Expand All @@ -114,13 +130,131 @@ https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-rep

...

^code nan-tagging (1 before, 1 after)
^code free-table (1 before, 1 after)

...

## nan tagging

...

^code define-nan-tagging (2 before, 1 after)

...

^code nan-tagging (2 before, 1 after)

...

^code end-if-nan-tagging (1 before, 2 after)

...

### numbers

**todo: remove comments**

...

^code number-val (1 before, 2 after)

...

^code num-to-value (1 before, 2 after)

...

^code double-union (1 before, 2 after)

// A union to let us reinterpret a double as raw bits and back.

...

^code as-number (2 before, 2 after)

...

^code value-to-num (1 before, 2 after)

**todo: split into smaller**
...

^code is-number (1 before, 2 after)

// If the NaN bits are set, it's not a number.

...

^code qnan (1 before, 2 after)

// The bits that must be set to indicate a quiet NaN.

...

### nil and singleton values

...

^code nil-val (2 before, 1 after)

...

^code tags (1 before, 2 after)

// Tag values for the different singleton values.

...

^code is-nil (2 before, 1 after)

...

### booleans

...

^code false-true-vals (2 before, 1 after)

...

^code end-if-nan-tagging (1 before, 1 after)
^code bool-val (2 before, 1 after)

...

^code as-bool (2 before, 1 after)

...

^code is-bool (2 before, 1 after)

...

### objects

...

^code obj-val (1 before, 2 after)

// The triple casting is necessary here to satisfy some compilers:
// 1. (uintptr_t) Convert the pointer to a number of the right size.
// 2. (uint64_t) Pad it up to 64 bits in 32-bit builds.
// 3. Or in the bits to make a tagged Nan.
// 4. Cast to a typedef'd value.

...

^code sign-bit (1 before, 2 after)

// A mask that selects the sign bit.

...

^code as-obj (1 before, 2 after)

...

^code is-obj (1 before, 2 after)

### value functions

...

Expand All @@ -139,4 +273,3 @@ https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-rep
^code end-values-equal (1 before, 1 after)

...

83 changes: 54 additions & 29 deletions c/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,61 +13,86 @@ typedef struct sObjString ObjString;
//< Strings forward-declare-obj
//> Optimization nan-tagging
#ifdef NAN_TAGGING
//> sign-bit

// A mask that selects the sign bit.
#define SIGN_BIT ((uint64_t)1 << 63)
//< sign-bit
//> qnan

// The bits that must be set to indicate a quiet NaN.
#define QNAN ((uint64_t)0x7ffc000000000000)
//< qnan
//> tags

// Tag values for the different singleton values.
#define TAG_NIL 1 // 01.
#define TAG_FALSE 2 // 10.
#define TAG_TRUE 3 // 11.
//< tags

typedef uint64_t Value;

#define IS_BOOL(v) (((v) & FALSE_VAL) == FALSE_VAL)
#define IS_NIL(v) ((v) == NIL_VAL)
// If the NaN bits are set, it's not a number.
#define IS_NUMBER(v) (((v) & QNAN) != QNAN)
#define IS_OBJ(v) (((v) & (QNAN | SIGN_BIT)) == (QNAN | SIGN_BIT))

#define AS_BOOL(v) ((v) == TRUE_VAL)
#define AS_NUMBER(v) valueToNum(v)
#define AS_OBJ(v) ((Obj*)(uintptr_t)((v) & ~(SIGN_BIT | QNAN)))

#define BOOL_VAL(boolean) ((boolean) ? TRUE_VAL : FALSE_VAL)
#define FALSE_VAL ((Value)(uint64_t)(QNAN | TAG_FALSE))
#define TRUE_VAL ((Value)(uint64_t)(QNAN | TAG_TRUE))
#define NIL_VAL ((Value)(uint64_t)(QNAN | TAG_NIL))
#define NUMBER_VAL(num) numToValue(num)
// The triple casting is necessary here to satisfy some compilers:
// 1. (uintptr_t) Convert the pointer to a number of the right size.
// 2. (uint64_t) Pad it up to 64 bits in 32-bit builds.
// 3. Or in the bits to make a tagged Nan.
// 4. Cast to a typedef'd value.
//> is-number

//> is-bool
#define IS_BOOL(v) (((v) & FALSE_VAL) == FALSE_VAL)
//< is-bool
//> is-nil
#define IS_NIL(v) ((v) == NIL_VAL)
//< is-nil
#define IS_NUMBER(v) (((v) & QNAN) != QNAN)
//< is-number
//> is-obj
#define IS_OBJ(v) (((v) & (QNAN | SIGN_BIT)) == (QNAN | SIGN_BIT))
//< is-obj
//> as-number

//> as-bool
#define AS_BOOL(v) ((v) == TRUE_VAL)
//< as-bool
#define AS_NUMBER(v) valueToNum(v)
//< as-number
//> as-obj
#define AS_OBJ(v) ((Obj*)(uintptr_t)((v) & ~(SIGN_BIT | QNAN)))
//< as-obj
//> number-val

//> bool-val
#define BOOL_VAL(b) ((b) ? TRUE_VAL : FALSE_VAL)
//< bool-val
//> false-true-vals
#define FALSE_VAL ((Value)(uint64_t)(QNAN | TAG_FALSE))
#define TRUE_VAL ((Value)(uint64_t)(QNAN | TAG_TRUE))
//< false-true-vals
//> nil-val
#define NIL_VAL ((Value)(uint64_t)(QNAN | TAG_NIL))
//< nil-val
#define NUMBER_VAL(num) numToValue(num)
//< number-val
//> obj-val
#define OBJ_VAL(obj) \
(Value)(SIGN_BIT | QNAN | (uint64_t)(uintptr_t)(obj))
//< obj-val
//> double-union

// A union to let us reinterpret a double as raw bits and back.
typedef union {
uint64_t bits64;
uint32_t bits32[2];
uint64_t bits;
double num;
} DoubleUnion;
//< double-union
//> value-to-num

static inline double valueToNum(Value value) {
DoubleUnion data;
data.bits64 = value;
data.bits = value;
return data.num;
}
//< value-to-num
//> num-to-value

static inline Value numToValue(double num) {
DoubleUnion data;
data.num = num;
return data.bits64;
return data.bits;
}
//< num-to-value

#else

Expand Down
1 change: 0 additions & 1 deletion site/contents.html
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ <h2><span class="num">III.</span><a href="a-bytecode-virtual-machine.html" name=
<li><span class="num">29.</span><a href="superclasses.html">Superclasses</a>
</li>
<li><span class="num">30.</span><a href="optimization.html">Optimization</a>
<a class="not-written" href="#not-written" title="This chapter hasn't been written yet!">(COMING SOON)</a>
</li>
</ul>

Expand Down

0 comments on commit 4e93be8

Please sign in to comment.