mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:18:11 +00:00
LibJS: Stop making shapes unique
We previously had a concept of unique shapes, which meant that they couldn't be shared between multiple objects. Object shapes became unique in three situations: - They were the shape of the global object. - They had more than 100 properties added to them. - They had one or more properties deleted from them. Unfortunately, unique shapes presented an annoying problem for inline caches, and we added a "unique shape serial number" for being able to tell that a unique shape had been mutated. This patch gets rid of the concept of unique shapes, simplifying all the caching code, since inline caches can now simply perform a shape check and then we're good. To make this possible, we now have the concept of delete transitions, which occur when a property is deleted from a shape. Note that this patch by itself introduces a performance regression in some situtations, since we now create a lot more shapes, and marking their property keys can be very heavy. This will be addressed in a subsequent patch.
This commit is contained in:
parent
ef86cf4646
commit
3d92c26445
8 changed files with 63 additions and 214 deletions
|
@ -1665,39 +1665,6 @@ void Compiler::compile_get_by_id(Bytecode::Op::GetById const& op)
|
|||
Assembler::Operand::Register(GPR1),
|
||||
slow_case);
|
||||
|
||||
// (!object->shape().is_unique() || object->shape().unique_shape_serial_number() == cache.unique_shape_serial_number)) {
|
||||
Assembler::Label fast_case;
|
||||
|
||||
// GPR1 = object->shape().is_unique()
|
||||
m_assembler.mov8(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Operand::Mem64BaseAndOffset(GPR2, Shape::is_unique_offset()));
|
||||
|
||||
m_assembler.jump_if(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Condition::EqualTo,
|
||||
Assembler::Operand::Imm(0),
|
||||
fast_case);
|
||||
|
||||
// GPR1 = object->shape().unique_shape_serial_number()
|
||||
m_assembler.mov(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Operand::Mem64BaseAndOffset(GPR2, Shape::unique_shape_serial_number_offset()));
|
||||
|
||||
// GPR2 = cache.unique_shape_serial_number
|
||||
m_assembler.mov(
|
||||
Assembler::Operand::Register(GPR2),
|
||||
Assembler::Operand::Mem64BaseAndOffset(ARG5, Bytecode::PropertyLookupCache::unique_shape_serial_number_offset()));
|
||||
|
||||
// if (GPR1 != GPR2) goto slow_case;
|
||||
m_assembler.jump_if(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Condition::NotEqualTo,
|
||||
Assembler::Operand::Register(GPR2),
|
||||
slow_case);
|
||||
|
||||
fast_case.link(m_assembler);
|
||||
|
||||
// return object->get_direct(*cache.property_offset);
|
||||
// GPR0 = object
|
||||
// GPR1 = *cache.property_offset * sizeof(Value)
|
||||
|
@ -1953,38 +1920,6 @@ void Compiler::compile_get_global(Bytecode::Op::GetGlobal const& op)
|
|||
Assembler::Operand::Register(GPR0),
|
||||
slow_case);
|
||||
|
||||
Assembler::Label fast_case {};
|
||||
|
||||
// GPR2 = shape->unique()
|
||||
m_assembler.mov8(
|
||||
Assembler::Operand::Register(GPR2),
|
||||
Assembler::Operand::Mem64BaseAndOffset(GPR0, Shape::is_unique_offset()));
|
||||
// if (!GPR2) goto fast_case;
|
||||
m_assembler.jump_if(
|
||||
Assembler::Operand::Register(GPR2),
|
||||
Assembler::Condition::EqualTo,
|
||||
Assembler::Operand::Imm(0),
|
||||
fast_case);
|
||||
|
||||
// GPR2 = shape->unique_shape_serial_number()
|
||||
m_assembler.mov(
|
||||
Assembler::Operand::Register(GPR2),
|
||||
Assembler::Operand::Mem64BaseAndOffset(GPR0, Shape::unique_shape_serial_number_offset()));
|
||||
|
||||
// GPR0 = cache.unique_shape_serial_number
|
||||
m_assembler.mov(
|
||||
Assembler::Operand::Register(GPR0),
|
||||
Assembler::Operand::Mem64BaseAndOffset(ARG2, Bytecode::PropertyLookupCache::unique_shape_serial_number_offset()));
|
||||
|
||||
// if (GPR2 != GPR0) goto slow_case;
|
||||
m_assembler.jump_if(
|
||||
Assembler::Operand::Register(GPR2),
|
||||
Assembler::Condition::NotEqualTo,
|
||||
Assembler::Operand::Register(GPR0),
|
||||
slow_case);
|
||||
|
||||
fast_case.link(m_assembler);
|
||||
|
||||
// accumulator = GPR1->get_direct(*cache.property_offset);
|
||||
// GPR0 = GPR1
|
||||
// GPR1 = *cache.property_offset * sizeof(Value)
|
||||
|
@ -2295,39 +2230,6 @@ void Compiler::compile_put_by_id(Bytecode::Op::PutById const& op)
|
|||
Assembler::Operand::Register(GPR1),
|
||||
slow_case);
|
||||
|
||||
// (!object->shape().is_unique() || object->shape().unique_shape_serial_number() == cache.unique_shape_serial_number)) {
|
||||
Assembler::Label fast_case;
|
||||
|
||||
// GPR1 = object->shape().is_unique()
|
||||
m_assembler.mov8(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Operand::Mem64BaseAndOffset(GPR2, Shape::is_unique_offset()));
|
||||
|
||||
m_assembler.jump_if(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Condition::EqualTo,
|
||||
Assembler::Operand::Imm(0),
|
||||
fast_case);
|
||||
|
||||
// GPR1 = object->shape().unique_shape_serial_number()
|
||||
m_assembler.mov(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Operand::Mem64BaseAndOffset(GPR2, Shape::unique_shape_serial_number_offset()));
|
||||
|
||||
// GPR2 = cache.unique_shape_serial_number
|
||||
m_assembler.mov(
|
||||
Assembler::Operand::Register(GPR2),
|
||||
Assembler::Operand::Mem64BaseAndOffset(ARG5, Bytecode::PropertyLookupCache::unique_shape_serial_number_offset()));
|
||||
|
||||
// if (GPR1 != GPR2) goto slow_case;
|
||||
m_assembler.jump_if(
|
||||
Assembler::Operand::Register(GPR1),
|
||||
Assembler::Condition::NotEqualTo,
|
||||
Assembler::Operand::Register(GPR2),
|
||||
slow_case);
|
||||
|
||||
fast_case.link(m_assembler);
|
||||
|
||||
// object->put_direct(*cache.property_offset, value);
|
||||
// GPR0 = object
|
||||
// GPR1 = *cache.property_offset * sizeof(Value)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue