[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75
ggaren at apple.com
ggaren at apple.com
Thu Oct 29 20:47:53 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit e514be74542edf577f2b0b88662bb60b1b36a2fb
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Oct 19 18:47:40 2009 +0000
Tightened up some instanceof code generation.
https://bugs.webkit.org/show_bug.cgi?id=30488
Patch by Geoffrey Garen <ggaren at apple.com> on 2009-10-17
Reviewed by Oliver Hunt.
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_instanceof):
(JSC::JIT::emitSlow_op_instanceof): No need to do object type checks -
cell type checks and ImplementsDefaultHasIntance checks implicitly
supersede object type checks.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49795 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 06b60ea..2e601b5 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,16 @@
+2009-10-17 Geoffrey Garen <ggaren at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Tightened up some instanceof code generation.
+ https://bugs.webkit.org/show_bug.cgi?id=30488
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof): No need to do object type checks -
+ cell type checks and ImplementsDefaultHasIntance checks implicitly
+ supersede object type checks.
+
2009-10-18 Kwang Yul Seo <skyul at company100.net>
Reviewed by Darin Adler.
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index 59bc403..e10d105 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -458,30 +458,20 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
unsigned baseVal = currentInstruction[3].u.operand;
unsigned proto = currentInstruction[4].u.operand;
- // Load the operands (baseVal, proto, and value respectively) into registers.
+ // Load the operands into registers.
// We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
- emitLoadPayload(proto, regT1);
- emitLoadPayload(baseVal, regT0);
emitLoadPayload(value, regT2);
+ emitLoadPayload(baseVal, regT0);
+ emitLoadPayload(proto, regT1);
- // Check that baseVal & proto are cells.
- emitJumpSlowCaseIfNotJSCell(proto);
+ // Check that value, baseVal, and proto are cells.
+ emitJumpSlowCaseIfNotJSCell(value);
emitJumpSlowCaseIfNotJSCell(baseVal);
+ emitJumpSlowCaseIfNotJSCell(proto);
- // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'.
+ // Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); // FIXME: Maybe remove this test.
- addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance))); // FIXME: TOT checks ImplementsDefaultHasInstance.
-
- // If value is not an Object, return false.
- emitLoadTag(value, regT0);
- Jump valueIsImmediate = branch32(NotEqual, regT0, Imm32(JSValue::CellTag));
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); // FIXME: Maybe remove this test.
-
- // Check proto is object.
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
@@ -489,16 +479,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
move(Imm32(JSValue::TrueTag), regT0);
Label loop(this);
- // Load the prototype of the object in regT2. If this is equal to regT1 - WIN!
+ // Load the prototype of the cell in regT2. If this is equal to regT1 - WIN!
// Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again.
loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
load32(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
Jump isInstance = branchPtr(Equal, regT2, regT1);
- branch32(NotEqual, regT2, Imm32(0), loop);
+ branchTest32(NonZero, regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- valueIsImmediate.link(this);
- valueIsNotObject.link(this);
move(Imm32(JSValue::FalseTag), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
@@ -513,11 +501,10 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
unsigned baseVal = currentInstruction[3].u.operand;
unsigned proto = currentInstruction[4].u.operand;
+ linkSlowCaseIfNotJSCell(iter, value);
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value);
@@ -1988,30 +1975,26 @@ void JIT::emit_op_new_object(Instruction* currentInstruction)
void JIT::emit_op_instanceof(Instruction* currentInstruction)
{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned value = currentInstruction[2].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
+ unsigned proto = currentInstruction[4].u.operand;
+
// Load the operands (baseVal, proto, and value respectively) into registers.
// We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
- emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
- emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);
- emitGetVirtualRegister(currentInstruction[2].u.operand, regT2);
+ emitGetVirtualRegister(value, regT2);
+ emitGetVirtualRegister(baseVal, regT0);
+ emitGetVirtualRegister(proto, regT1);
// Check that baseVal & proto are cells.
- emitJumpSlowCaseIfNotJSCell(regT0);
- emitJumpSlowCaseIfNotJSCell(regT1);
+ emitJumpSlowCaseIfNotJSCell(regT2, value);
+ emitJumpSlowCaseIfNotJSCell(regT0, baseVal);
+ emitJumpSlowCaseIfNotJSCell(regT1, proto);
- // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'.
+ // Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
- // If value is not an Object, return false.
- Jump valueIsImmediate = emitJumpIfNotJSCell(regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
-
- // Check proto is object.
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
-
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
@@ -2023,16 +2006,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
Jump isInstance = branchPtr(Equal, regT2, regT1);
- branchPtr(NotEqual, regT2, ImmPtr(JSValue::encode(jsNull())), loop);
+ emitJumpIfJSCell(regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- valueIsImmediate.link(this);
- valueIsNotObject.link(this);
move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
isInstance.link(this);
- emitPutVirtualRegister(currentInstruction[1].u.operand);
+ emitPutVirtualRegister(dst);
}
void JIT::emit_op_new_func(Instruction* currentInstruction)
@@ -3066,16 +3047,20 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase
void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned value = currentInstruction[2].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
+ unsigned proto = currentInstruction[4].u.operand;
+
+ linkSlowCaseIfNotJSCell(iter, value);
+ linkSlowCaseIfNotJSCell(iter, baseVal);
+ linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
- stubCall.addArgument(currentInstruction[2].u.operand, regT2);
- stubCall.addArgument(currentInstruction[3].u.operand, regT2);
- stubCall.addArgument(currentInstruction[4].u.operand, regT2);
- stubCall.call(currentInstruction[1].u.operand);
+ stubCall.addArgument(value, regT2);
+ stubCall.addArgument(baseVal, regT2);
+ stubCall.addArgument(proto, regT2);
+ stubCall.call(dst);
}
void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list