diff options
| author | Po Lu | 2023-08-01 14:54:30 +0800 |
|---|---|---|
| committer | Po Lu | 2023-08-01 14:54:30 +0800 |
| commit | b022398b8f0a03f0e1b3ec8df41a439cdbe5bd19 (patch) | |
| tree | 376cdb3f4d31c4feeea1d3a90aadc69612c27315 /src | |
| parent | 202ddc0137ac523f4b455ce8cfc7eb01d6384349 (diff) | |
| download | emacs-b022398b8f0a03f0e1b3ec8df41a439cdbe5bd19.tar.gz emacs-b022398b8f0a03f0e1b3ec8df41a439cdbe5bd19.zip | |
Micro-optimize PUSHW/PUSHB
* src/sfnt.c (CHECK_STACK_AVAILABLE): New macro.
(PUSH):
(PUSH_UNCHECKED): Always define to unchecked versions,
even if TEST.
(PUSH2_UNCHECKED): New macro.
(NPUSHB):
(NPUSHW):
(PUSHB):
(PUSHW): Check the number of remaining stack elements
once.
(stack_overflow_test_args): Expect zero stack arguments.
Diffstat (limited to 'src')
| -rw-r--r-- | src/sfnt.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/src/sfnt.c b/src/sfnt.c index 3f1639b3734..876db70bcda 100644 --- a/src/sfnt.c +++ b/src/sfnt.c | |||
| @@ -5708,6 +5708,17 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 5708 | TRAP ("stack underflow"); \ | 5708 | TRAP ("stack underflow"); \ |
| 5709 | } | 5709 | } |
| 5710 | 5710 | ||
| 5711 | #define CHECK_STACK_AVAILABLE(n) \ | ||
| 5712 | { \ | ||
| 5713 | char *stack_end; \ | ||
| 5714 | \ | ||
| 5715 | stack_end \ | ||
| 5716 | = (char *) interpreter->twilight_x; \ | ||
| 5717 | if (((char *) (interpreter->SP + (n)) \ | ||
| 5718 | > stack_end)) \ | ||
| 5719 | TRAP ("stack overflow"); \ | ||
| 5720 | } | ||
| 5721 | |||
| 5711 | #define CHECK_PREP() \ | 5722 | #define CHECK_PREP() \ |
| 5712 | if (!is_prep) \ | 5723 | if (!is_prep) \ |
| 5713 | TRAP ("instruction executed not valid" \ | 5724 | TRAP ("instruction executed not valid" \ |
| @@ -5756,7 +5767,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 5756 | ? (TRAP ("stack underflow"), 0) \ | 5767 | ? (TRAP ("stack underflow"), 0) \ |
| 5757 | : *(interpreter->SP - 1)) | 5768 | : *(interpreter->SP - 1)) |
| 5758 | 5769 | ||
| 5759 | #ifndef TEST | 5770 | #if !defined TEST || !0 |
| 5760 | 5771 | ||
| 5761 | #define PUSH(value) \ | 5772 | #define PUSH(value) \ |
| 5762 | { \ | 5773 | { \ |
| @@ -5774,7 +5785,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 5774 | interpreter->SP++; \ | 5785 | interpreter->SP++; \ |
| 5775 | } | 5786 | } |
| 5776 | 5787 | ||
| 5777 | #else | 5788 | #else /* TEST && 0 */ |
| 5778 | 5789 | ||
| 5779 | #define PUSH(value) \ | 5790 | #define PUSH(value) \ |
| 5780 | { \ | 5791 | { \ |
| @@ -5792,12 +5803,14 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 5792 | 5803 | ||
| 5793 | #define PUSH_UNCHECKED(value) PUSH (value) | 5804 | #define PUSH_UNCHECKED(value) PUSH (value) |
| 5794 | 5805 | ||
| 5795 | #endif | 5806 | #endif /* TEST && 0 */ |
| 5796 | 5807 | ||
| 5797 | #define PUSH2(high, low) \ | 5808 | #define PUSH2_UNCHECKED(high, low) \ |
| 5798 | { \ | 5809 | { \ |
| 5799 | PUSH ((int16_t) ((int8_t) high) << 8 \ | 5810 | int16_t word; \ |
| 5800 | | low); \ | 5811 | \ |
| 5812 | word = (((int8_t) high) << 8 | low); \ | ||
| 5813 | PUSH_UNCHECKED (word); \ | ||
| 5801 | } \ | 5814 | } \ |
| 5802 | 5815 | ||
| 5803 | #define SRP0() \ | 5816 | #define SRP0() \ |
| @@ -6097,6 +6110,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6097 | #define NPUSHB() \ | 6110 | #define NPUSHB() \ |
| 6098 | { \ | 6111 | { \ |
| 6099 | int b, nbytes, IP; \ | 6112 | int b, nbytes, IP; \ |
| 6113 | unsigned char *ip; \ | ||
| 6100 | \ | 6114 | \ |
| 6101 | if ((IP = interpreter->IP + 1) \ | 6115 | if ((IP = interpreter->IP + 1) \ |
| 6102 | >= interpreter->num_instructions) \ | 6116 | >= interpreter->num_instructions) \ |
| @@ -6109,8 +6123,10 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6109 | > interpreter->num_instructions) \ | 6123 | > interpreter->num_instructions) \ |
| 6110 | TRAP ("args to NPUSHB lie outside IS"); \ | 6124 | TRAP ("args to NPUSHB lie outside IS"); \ |
| 6111 | \ | 6125 | \ |
| 6126 | CHECK_STACK_AVAILABLE (nbytes); \ | ||
| 6127 | ip = interpreter->instructions; \ | ||
| 6112 | for (b = IP + 1; b < IP + 1 + nbytes; ++b) \ | 6128 | for (b = IP + 1; b < IP + 1 + nbytes; ++b) \ |
| 6113 | PUSH (interpreter->instructions[b]); \ | 6129 | PUSH_UNCHECKED (ip[b]); \ |
| 6114 | \ | 6130 | \ |
| 6115 | interpreter->IP += nbytes + 1; \ | 6131 | interpreter->IP += nbytes + 1; \ |
| 6116 | } | 6132 | } |
| @@ -6118,6 +6134,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6118 | #define NPUSHW() \ | 6134 | #define NPUSHW() \ |
| 6119 | { \ | 6135 | { \ |
| 6120 | int b, nbytes, IP; \ | 6136 | int b, nbytes, IP; \ |
| 6137 | unsigned char *ip; \ | ||
| 6121 | \ | 6138 | \ |
| 6122 | if ((IP = interpreter->IP + 1) \ | 6139 | if ((IP = interpreter->IP + 1) \ |
| 6123 | >= interpreter->num_instructions) \ | 6140 | >= interpreter->num_instructions) \ |
| @@ -6130,10 +6147,11 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6130 | > interpreter->num_instructions) \ | 6147 | > interpreter->num_instructions) \ |
| 6131 | TRAP ("args to NPUSHW lie outside IS"); \ | 6148 | TRAP ("args to NPUSHW lie outside IS"); \ |
| 6132 | \ | 6149 | \ |
| 6150 | CHECK_STACK_AVAILABLE (nbytes / 2); \ | ||
| 6151 | ip = interpreter->instructions; \ | ||
| 6133 | for (b = IP + 1; b < IP + 1 + nbytes; \ | 6152 | for (b = IP + 1; b < IP + 1 + nbytes; \ |
| 6134 | b += 2) \ | 6153 | b += 2) \ |
| 6135 | PUSH2 (interpreter->instructions[b], \ | 6154 | PUSH2_UNCHECKED (ip[b], ip[b + 1]); \ |
| 6136 | interpreter->instructions[b + 1]); \ | ||
| 6137 | \ | 6155 | \ |
| 6138 | interpreter->IP += nbytes + 1; \ | 6156 | interpreter->IP += nbytes + 1; \ |
| 6139 | } | 6157 | } |
| @@ -6634,6 +6652,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6634 | #define PUSHB() \ | 6652 | #define PUSHB() \ |
| 6635 | { \ | 6653 | { \ |
| 6636 | int b, nbytes, IP; \ | 6654 | int b, nbytes, IP; \ |
| 6655 | unsigned char *ip; \ | ||
| 6637 | \ | 6656 | \ |
| 6638 | IP = interpreter->IP; \ | 6657 | IP = interpreter->IP; \ |
| 6639 | nbytes = opcode - 0xb0 + 1; \ | 6658 | nbytes = opcode - 0xb0 + 1; \ |
| @@ -6642,8 +6661,10 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6642 | > interpreter->num_instructions) \ | 6661 | > interpreter->num_instructions) \ |
| 6643 | TRAP ("args to PUSHB lie outside IS"); \ | 6662 | TRAP ("args to PUSHB lie outside IS"); \ |
| 6644 | \ | 6663 | \ |
| 6664 | CHECK_STACK_AVAILABLE (nbytes); \ | ||
| 6665 | ip = interpreter->instructions; \ | ||
| 6645 | for (b = IP + 1; b < IP + nbytes + 1; ++b) \ | 6666 | for (b = IP + 1; b < IP + nbytes + 1; ++b) \ |
| 6646 | PUSH (interpreter->instructions[b]); \ | 6667 | PUSH_UNCHECKED (ip[b]); \ |
| 6647 | \ | 6668 | \ |
| 6648 | interpreter->IP += nbytes; \ | 6669 | interpreter->IP += nbytes; \ |
| 6649 | } | 6670 | } |
| @@ -6651,6 +6672,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6651 | #define PUSHW() \ | 6672 | #define PUSHW() \ |
| 6652 | { \ | 6673 | { \ |
| 6653 | int b, nbytes, IP; \ | 6674 | int b, nbytes, IP; \ |
| 6675 | unsigned char *ip; \ | ||
| 6654 | \ | 6676 | \ |
| 6655 | IP = interpreter->IP; \ | 6677 | IP = interpreter->IP; \ |
| 6656 | nbytes = (opcode - 0xb8 + 1) * 2; \ | 6678 | nbytes = (opcode - 0xb8 + 1) * 2; \ |
| @@ -6659,10 +6681,11 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6659 | > interpreter->num_instructions) \ | 6681 | > interpreter->num_instructions) \ |
| 6660 | TRAP ("args to PUSHW lie outside IS"); \ | 6682 | TRAP ("args to PUSHW lie outside IS"); \ |
| 6661 | \ | 6683 | \ |
| 6684 | CHECK_STACK_AVAILABLE (nbytes / 2); \ | ||
| 6685 | ip = interpreter->instructions; \ | ||
| 6662 | for (b = IP + 1; b < IP + nbytes + 1; \ | 6686 | for (b = IP + 1; b < IP + nbytes + 1; \ |
| 6663 | b += 2) \ | 6687 | b += 2) \ |
| 6664 | PUSH2 (interpreter->instructions[b], \ | 6688 | PUSH2_UNCHECKED (ip[b], ip[b + 1]); \ |
| 6665 | interpreter->instructions[b + 1]); \ | ||
| 6666 | \ | 6689 | \ |
| 6667 | interpreter->IP += nbytes; \ | 6690 | interpreter->IP += nbytes; \ |
| 6668 | } | 6691 | } |
| @@ -16080,8 +16103,8 @@ static struct sfnt_generic_test_args pushw_test_args = | |||
| 16080 | 16103 | ||
| 16081 | static struct sfnt_generic_test_args stack_overflow_test_args = | 16104 | static struct sfnt_generic_test_args stack_overflow_test_args = |
| 16082 | { | 16105 | { |
| 16083 | (uint32_t[100]) { }, | 16106 | (uint32_t[]) { }, |
| 16084 | 100, | 16107 | 0, |
| 16085 | true, | 16108 | true, |
| 16086 | 0, | 16109 | 0, |
| 16087 | }; | 16110 | }; |