mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-19 07:26:26 +00:00
Bug 957659 - slim down WidgetKeyboardEvent::GetDOMKeyName; r=masayuki
Instead of calling nsAString::Assign several hundred times along with a switch statement that may or may not get translated into a jump table, let's implement our own lookup table that we can guarantee will be constant time. The KeyNameTable struct is used instead of the more obvious |const char* const table[]| idiom to avoid runtime relocations.
This commit is contained in:
parent
b07161b5dc
commit
7cc4b6c4c7
@ -127,20 +127,7 @@ public:
|
||||
}
|
||||
|
||||
static void GetDOMKeyName(mozilla::KeyNameIndex aKeyNameIndex,
|
||||
nsAString& aKeyName)
|
||||
{
|
||||
#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
|
||||
case KEY_NAME_INDEX_##aCPPName: \
|
||||
aKeyName.Assign(NS_LITERAL_STRING(aDOMKeyName)); return;
|
||||
switch (aKeyNameIndex) {
|
||||
#include "nsDOMKeyNameList.h"
|
||||
case KEY_NAME_INDEX_USE_STRING:
|
||||
default:
|
||||
aKeyName.Truncate();
|
||||
return;
|
||||
}
|
||||
#undef NS_DEFINE_KEYNAME
|
||||
}
|
||||
nsAString& aKeyName);
|
||||
|
||||
void AssignKeyEventData(const WidgetKeyboardEvent& aEvent, bool aCopyTargets)
|
||||
{
|
||||
|
@ -237,4 +237,74 @@ WidgetEvent::IsAllowedToDispatchDOMEvent() const
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* mozilla::WidgetKeyboardEvent (TextEvents.h)
|
||||
******************************************************************************/
|
||||
|
||||
/*static*/ void
|
||||
WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
|
||||
nsAString& aKeyName)
|
||||
{
|
||||
// The expected way to implement this function would be to use a
|
||||
// switch statement. By using a table-based implementation, below, we
|
||||
// ensure that this function executes in constant time in cases where
|
||||
// compilers wouldn't be able to convert the switch statement to a
|
||||
// jump table. This table-based implementation also minimizes the
|
||||
// space required by the code and data.
|
||||
#define KEY_STR_NUM_INTERNAL(line) key##line
|
||||
#define KEY_STR_NUM(line) KEY_STR_NUM_INTERNAL(line)
|
||||
|
||||
// Catch non-ASCII DOM key names in our key name list.
|
||||
#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
|
||||
static_assert(sizeof(aDOMKeyName) == MOZ_ARRAY_LENGTH(aDOMKeyName), \
|
||||
"Invalid DOM key name");
|
||||
#include "nsDOMKeyNameList.h"
|
||||
#undef NS_DEFINE_KEYNAME
|
||||
|
||||
struct KeyNameTable
|
||||
{
|
||||
#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
|
||||
char16_t KEY_STR_NUM(__LINE__)[sizeof(aDOMKeyName)];
|
||||
#include "nsDOMKeyNameList.h"
|
||||
#undef NS_DEFINE_KEYNAME
|
||||
};
|
||||
|
||||
static const KeyNameTable kKeyNameTable = {
|
||||
#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) MOZ_UTF16(aDOMKeyName),
|
||||
#include "nsDOMKeyNameList.h"
|
||||
#undef NS_DEFINE_KEYNAME
|
||||
};
|
||||
|
||||
static const uint16_t kKeyNameOffsets[] = {
|
||||
#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
|
||||
offsetof(struct KeyNameTable, KEY_STR_NUM(__LINE__)),
|
||||
#include "nsDOMKeyNameList.h"
|
||||
#undef NS_DEFINE_KEYNAME
|
||||
// Include this entry so we can compute lengths easily.
|
||||
sizeof(kKeyNameTable)
|
||||
};
|
||||
|
||||
// Use the sizeof trick rather than MOZ_ARRAY_LENGTH to avoid problems
|
||||
// with constexpr functions called inside static_assert with some
|
||||
// compilers.
|
||||
static_assert(KEY_NAME_INDEX_USE_STRING ==
|
||||
(sizeof(kKeyNameOffsets)/sizeof(kKeyNameOffsets[0])) - 1,
|
||||
"Invalid enumeration values!");
|
||||
|
||||
if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
|
||||
aKeyName.Truncate();
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t offset = kKeyNameOffsets[aKeyNameIndex];
|
||||
uint16_t nextOffset = kKeyNameOffsets[aKeyNameIndex + 1];
|
||||
const char16_t* table = reinterpret_cast<const char16_t*>(&kKeyNameTable);
|
||||
|
||||
// Subtract off 1 for the null terminator.
|
||||
aKeyName.Assign(table + offset, nextOffset - offset - 1);
|
||||
|
||||
#undef KEY_STR_NUM
|
||||
#undef KEY_STR_NUM_INTERNAL
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
x
Reference in New Issue
Block a user