aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-08-01 14:54:30 +0800
committerPo Lu2023-08-01 14:54:30 +0800
commitb022398b8f0a03f0e1b3ec8df41a439cdbe5bd19 (patch)
tree376cdb3f4d31c4feeea1d3a90aadc69612c27315 /src
parent202ddc0137ac523f4b455ce8cfc7eb01d6384349 (diff)
downloademacs-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.c51
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
16081static struct sfnt_generic_test_args stack_overflow_test_args = 16104static 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 };