Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

300300 0F338E141BF0276C0013C88F /* B3ValueKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E081BF0276C0013C88F /* B3ValueKey.cpp */; };
301301 0F338E151BF0276C0013C88F /* B3ValueKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E091BF0276C0013C88F /* B3ValueKey.h */; };
302302 0F338E161BF0276C0013C88F /* B3ValueKeyInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */; };
 303 0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */; };
 304 0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */; };
 305 0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */; };
 306 0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */; };
303307 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
304308 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
305309 0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };

23392343 0F338E081BF0276C0013C88F /* B3ValueKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3ValueKey.cpp; path = b3/B3ValueKey.cpp; sourceTree = "<group>"; };
23402344 0F338E091BF0276C0013C88F /* B3ValueKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKey.h; path = b3/B3ValueKey.h; sourceTree = "<group>"; };
23412345 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKeyInlines.h; path = b3/B3ValueKeyInlines.h; sourceTree = "<group>"; };
 2346 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BlockInsertionSet.cpp; path = b3/B3BlockInsertionSet.cpp; sourceTree = "<group>"; };
 2347 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BlockInsertionSet.h; path = b3/B3BlockInsertionSet.h; sourceTree = "<group>"; };
 2348 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacros.cpp; path = b3/B3LowerMacros.cpp; sourceTree = "<group>"; };
 2349 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacros.h; path = b3/B3LowerMacros.h; sourceTree = "<group>"; };
23422350 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
23432351 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
23442352 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = "<group>"; };

44324440 0FEC84B71BDACDAC0080FF74 /* B3BasicBlock.h */,
44334441 0FEC84B81BDACDAC0080FF74 /* B3BasicBlockInlines.h */,
44344442 0FEC84B91BDACDAC0080FF74 /* B3BasicBlockUtils.h */,
 4443 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */,
 4444 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */,
44354445 0FEC84BA1BDACDAC0080FF74 /* B3BlockWorklist.h */,
44364446 0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */,
44374447 0F338DF81BE96AA80013C88F /* B3CCallValue.h */,

44734483 0FEC85B41BE1462F0080FF74 /* B3InsertionSet.cpp */,
44744484 0FEC85B51BE1462F0080FF74 /* B3InsertionSet.h */,
44754485 0FEC85B61BE1462F0080FF74 /* B3InsertionSetInlines.h */,
 4486 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */,
 4487 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */,
44764488 0FEC84D31BDACDAC0080FF74 /* B3LowerToAir.cpp */,
44774489 0FEC84D41BDACDAC0080FF74 /* B3LowerToAir.h */,
44784490 0FEC84D51BDACDAC0080FF74 /* B3MemoryValue.cpp */,

66666678 0FEC85381BDACDAC0080FF74 /* B3SwitchCase.h in Headers */,
66676679 0FEC853A1BDACDAC0080FF74 /* B3SwitchValue.h in Headers */,
66686680 0F4570411BE584CA0062A629 /* B3TimingScope.h in Headers */,
 6681 0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */,
66696682 0FEC853C1BDACDAC0080FF74 /* B3Type.h in Headers */,
66706683 0FEC853E1BDACDAC0080FF74 /* B3UpsilonValue.h in Headers */,
66716684 0FEC85401BDACDAC0080FF74 /* B3UseCounts.h in Headers */,

67656778 C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,
67666779 C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
67676780 C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */,
 6781 0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */,
67686782 C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */,
67696783 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
67706784 9959E92B1BD17FA4001AA413 /* cssmin.py in Headers */,

83108324 147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */,
83118325 14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */,
83128326 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
 8327 0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */,
83138328 0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
83148329 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */,
83158330 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,

84828497 0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
84838498 0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
84848499 0FEA0A09170513DB00BB722C /* FTLCapabilities.cpp in Sources */,
 8500 0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */,
84858501 0FEA0A271709623B00BB722C /* FTLCommonValues.cpp in Sources */,
84868502 0FEA0A0B170513DB00BB722C /* FTLCompile.cpp in Sources */,
84878503 0FE95F7918B5694700B531FB /* FTLDataSection.cpp in Sources */,
192259

Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

@@public:
247247 m_assembler.imull_i32r(src, imm.m_value, dest);
248248 }
249249
 250 void x86ConvertToDoubleWord32()
 251 {
 252 m_assembler.cdq();
 253 }
 254
 255 void x86ConvertToDoubleWord32(RegisterID eax, RegisterID edx)
 256 {
 257 ASSERT_UNUSED(eax, eax == X86Register::eax);
 258 ASSERT_UNUSED(edx, edx == X86Register::eax);
 259 x86ConvertToDoubleWord32();
 260 }
 261
 262 void x86Div32(RegisterID denominator)
 263 {
 264 m_assembler.idivl_r(denominator);
 265 }
 266
 267 void x86Div32(RegisterID eax, RegisterID edx, RegisterID denominator)
 268 {
 269 ASSERT_UNUSED(eax, eax == X86Register::eax);
 270 ASSERT_UNUSED(edx, edx == X86Register::eax);
 271 x86Di32(denominator);
 272 }
 273
250274 void neg32(RegisterID srcDest)
251275 {
252276 m_assembler.negl_r(srcDest);
192259

Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

@@public:
386386 m_assembler.imulq_rr(src, dest);
387387 }
388388
 389 void x86ConvertToDoubleWord64()
 390 {
 391 m_assembler.cdqq();
 392 }
 393
 394 void x86ConvertToDoubleWord64(RegisterID rax, RegisterID rdx)
 395 {
 396 ASSERT_UNUSED(rax, rax == X86Register::eax);
 397 ASSERT_UNUSED(rdx, rdx == X86Register::eax);
 398 x86ConvertToDoubleWord64();
 399 }
 400
 401 void x86Div64(RegisterID denominator)
 402 {
 403 m_assembler.idivq_r(denominator);
 404 }
 405
 406 void x86Div64(RegisterID rax, RegisterID rdx, RegisterID denominator)
 407 {
 408 ASSERT_UNUSED(rax, rax == X86Registers::eax);
 409 ASSERT_UNUSED(rdx, rdx == X86Registers::edx);
 410 x86Div64(denominator);
 411 }
 412
389413 void neg64(RegisterID dest)
390414 {
391415 m_assembler.negq_r(dest);
192259

Source/JavaScriptCore/assembler/X86Assembler.h

@@public:
962962 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
963963 }
964964
 965 void idivq_r(RegisterID dst)
 966 {
 967 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
 968 }
 969
965970 // Comparisons:
966971
967972 void cmpl_rr(RegisterID src, RegisterID dst)

@@public:
12841289 m_formatter.oneByteOp(OP_CDQ);
12851290 }
12861291
 1292 void cdqq()
 1293 {
 1294 m_formatter.oneByteOp64(OP_CDQ);
 1295 }
 1296
12871297 void fstps(int offset, RegisterID base)
12881298 {
12891299 m_formatter.oneByteOp(OP_ESCAPE_D9, ESCAPE_D9_FSTP_singleReal, base, offset);
192259

Source/JavaScriptCore/b3/B3BasicBlock.cpp

@@void BasicBlock::append(Value* value)
5252 m_values.append(value);
5353}
5454
 55void BasicBlock::replaceLast(Procedure& proc, Value* value)
 56{
 57 proc.deleteValue(last());
 58 last() = value;
 59}
 60
 61Value* BasicBlock::appendIntConstant(Procedure& proc, Origin origin, Type type, int64_t value)
 62{
 63 Value* result = proc.addIntConstant(origin, type, value);
 64 append(result);
 65 return result;
 66}
 67
 68Value* BasicBlock::appendIntConstant(Procedure& proc, Value* likeValue, int64_t value)
 69{
 70 return appendIntConstant(proc, likeValue->origin(), likeValue->type(), value);
 71}
 72
5573bool BasicBlock::addPredecessor(BasicBlock* block)
5674{
5775 return B3::addPredecessor(this, block);
192259

Source/JavaScriptCore/b3/B3BasicBlock.h

2929#if ENABLE(B3_JIT)
3030
3131#include "B3FrequentedBlock.h"
 32#include "B3Origin.h"
3233#include "B3SuccessorCollection.h"
 34#include "B3Type.h"
3335#include <wtf/Vector.h>
3436
3537namespace JSC { namespace B3 {
3638
 39class BlockInsertionSet;
3740class InsertionSet;
3841class Procedure;
3942class Value;

@@public:
6871 ValueList& values() { return m_values; }
6972
7073 JS_EXPORT_PRIVATE void append(Value*);
 74 JS_EXPORT_PRIVATE void replaceLast(Procedure&, Value*);
7175
7276 template<typename ValueType, typename... Arguments>
7377 ValueType* appendNew(Procedure&, Arguments...);
7478
 79 Value* appendIntConstant(Procedure&, Origin, Type, int64_t value);
 80 Value* appendIntConstant(Procedure&, Value* likeValue, int64_t value);
 81
 82 template<typename ValueType, typename... Arguments>
 83 ValueType* replaceLastWithNew(Procedure&, Arguments...);
 84
7585 unsigned numSuccessors() const;
7686 const FrequentedBlock& successor(unsigned index) const;
7787 FrequentedBlock& successor(unsigned index);

@@public:
100110 void deepDump(PrintStream&) const;
101111
102112private:
 113 friend class BlockInsertionSet;
103114 friend class InsertionSet;
104115 friend class Procedure;
105116
192259

Source/JavaScriptCore/b3/B3BasicBlockInlines.h

@@ValueType* BasicBlock::appendNew(Procedu
4242 return result;
4343}
4444
 45template<typename ValueType, typename... Arguments>
 46ValueType* BasicBlock::replaceLastWithNew(Procedure& procedure, Arguments... arguments)
 47{
 48 ValueType* result = procedure.add<ValueType>(arguments...);
 49 replaceLast(procedure, result);
 50 return result;
 51}
 52
4553inline unsigned BasicBlock::numSuccessors() const
4654{
4755 return last()->as<ControlValue>()->numSuccessors();
192259

Source/JavaScriptCore/b3/B3BlockInsertionSet.cpp

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "B3BlockInsertionSet.h"
 28
 29#if ENABLE(B3_JIT)
 30
 31#include "B3BasicBlockInlines.h"
 32#include "B3InsertionSet.h"
 33#include "B3ProcedureInlines.h"
 34#include <wtf/BubbleSort.h>
 35
 36namespace JSC { namespace B3 {
 37
 38BlockInsertionSet::BlockInsertionSet(Procedure &proc)
 39 : m_proc(proc)
 40{
 41}
 42
 43BlockInsertionSet::~BlockInsertionSet() { }
 44
 45void BlockInsertionSet::insert(BlockInsertion&& insertion)
 46{
 47 m_insertions.append(WTF::move(insertion));
 48}
 49
 50BasicBlock* BlockInsertionSet::insert(unsigned index, double frequency)
 51{
 52 std::unique_ptr<BasicBlock> block(new BasicBlock(UINT_MAX, frequency));
 53 BasicBlock* result = block.get();
 54 insert(BlockInsertion(index, WTF::move(block)));
 55 return result;
 56}
 57
 58BasicBlock* BlockInsertionSet::insertBefore(BasicBlock* before, double frequency)
 59{
 60 return insert(before->index(), frequency == frequency ? frequency : before->frequency());
 61}
 62
 63BasicBlock* BlockInsertionSet::splitForward(
 64 BasicBlock* block, unsigned& valueIndex, InsertionSet* insertionSet, double frequency)
 65{
 66 Value* value = block->at(valueIndex);
 67
 68 BasicBlock* result = insertBefore(block, frequency);
 69 result->m_values.resize(valueIndex + 1);
 70 for (unsigned i = valueIndex; i--;)
 71 result->m_values[i] = block->m_values[i];
 72 result->m_values[valueIndex] =
 73 m_proc.add<ControlValue>(Jump, value->origin(), FrequentedBlock(block));
 74
 75 if (insertionSet)
 76 insertionSet->execute(result);
 77
 78 block->m_values.remove(0, valueIndex);
 79
 80 valueIndex = 0;
 81
 82 return result;
 83}
 84
 85bool BlockInsertionSet::execute()
 86{
 87 if (m_insertions.isEmpty())
 88 return false;
 89
 90 // We allow insertions to be given to us in any order. So, we need to sort them before
 91 // running WTF::executeInsertions. We strongly prefer a stable sort and we want it to be
 92 // fast, so we use bubble sort.
 93 bubbleSort(m_insertions.begin(), m_insertions.end());
 94
 95 executeInsertions(m_proc.m_blocks, m_insertions);
 96
 97 // Prune out empty entries. This isn't strictly necessary but it's
 98 // healthy to keep the block list from growing.
 99 m_proc.m_blocks.removeAllMatching(
 100 [&] (std::unique_ptr<BasicBlock>& blockPtr) -> bool {
 101 return !blockPtr;
 102 });
 103
 104 // Make sure that the blocks know their new indices.
 105 for (unsigned i = 0; i < m_proc.m_blocks.size(); ++i)
 106 m_proc.m_blocks[i]->m_index = i;
 107
 108 return true;
 109}
 110
 111} } // namespace JSC::B3
 112
 113#endif // ENABLE(B3_JIT)
 114
0

Source/JavaScriptCore/b3/B3BlockInsertionSet.h

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef B3BlockInsertionSet_h
 27#define B3BlockInsertionSet_h
 28
 29#if ENABLE(B3_JIT)
 30
 31#include "B3Procedure.h"
 32#include <wtf/Insertion.h>
 33#include <wtf/Vector.h>
 34
 35namespace JSC { namespace B3 {
 36
 37class InsertionSet;
 38
 39typedef WTF::Insertion<std::unique_ptr<BasicBlock>> BlockInsertion;
 40
 41class BlockInsertionSet {
 42public:
 43 BlockInsertionSet(Procedure&);
 44 ~BlockInsertionSet();
 45
 46 void insert(BlockInsertion&&);
 47
 48 // Insert a new block at a given index.
 49 BasicBlock* insert(unsigned index, double frequency = PNaN);
 50
 51 // Inserts a new block before the given block. Usually you will not pass the frequency
 52 // argument. Passing PNaN causes us to just use the frequency of the 'before' block. That's
 53 // usually what you want.
 54 BasicBlock* insertBefore(BasicBlock* before, double frequency = PNaN);
 55
 56 // A helper to split a block when forward iterating over it. It creates a new block to hold
 57 // everything before the instruction at valueIndex. The current block is left with
 58 // everything at and after valueIndex. If the optional InsertionSet is provided, it will get
 59 // executed on the newly created block - this makes sense if you had previously inserted
 60 // things into the original block, since the newly created block will be indexed identically
 61 // to hold this block was indexed for all values prior to valueIndex. After this runs, it
 62 // sets valueIndex to zero. This allows you to use this method for things like:
 63 //
 64 // for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
 65 // Value* value = block->at(valueIndex);
 66 // if (value->opcode() == Foo) {
 67 // BasicBlock* predecessor =
 68 // m_blockInsertionSet.splitForward(block, valueIndex, &m_insertionSet);
 69 // ... // Now you can append to predecessor, insert new blocks before 'block', and
 70 // ... // you can use m_insertionSet to insert more thing before 'value'.
 71 // }
 72 // }
 73 BasicBlock* splitForward(
 74 BasicBlock* block, unsigned& valueIndex, InsertionSet* = nullptr,
 75 double frequency = PNaN);
 76
 77 bool execute();
 78
 79private:
 80 Procedure& m_proc;
 81 Vector<BlockInsertion, 8> m_insertions;
 82};
 83
 84} } // namespace JSC::B3
 85
 86#endif // ENABLE(B3_JIT)
 87
 88#endif // B3BlockInsertionSet_h
 89
0

Source/JavaScriptCore/b3/B3Common.h

@@inline bool isRepresentableAs(double val
9494 return isRepresentableAsImpl<ResultType, double, int64_t>(value);
9595}
9696
 97inline int32_t chillDiv(int32_t num, int32_t den)
 98{
 99 if (!den)
 100 return 0;
 101 if (den == -1 && num == -2147483647 - 1)
 102 return num;
 103 return num / den;
 104}
 105
 106inline int64_t chillDiv(int64_t num, int64_t den)
 107{
 108 if (!den)
 109 return 0;
 110 if (den == -1 && num == -9223372036854775807ll - 1)
 111 return num;
 112 return num / den;
 113}
 114
97115} } // namespace JSC::B3
98116
99117#endif // ENABLE(B3_JIT)
192259

Source/JavaScriptCore/b3/B3Const32Value.cpp

@@Value* Const32Value::addConstant(Procedu
4747 return proc.add<Const32Value>(origin(), m_value + other);
4848}
4949
50 Value* Const32Value::addConstant(Procedure& proc, Value* other) const
 50Value* Const32Value::addConstant(Procedure& proc, const Value* other) const
5151{
5252 if (!other->hasInt32())
5353 return nullptr;
5454 return proc.add<Const32Value>(origin(), m_value + other->asInt32());
5555}
5656
57 Value* Const32Value::subConstant(Procedure& proc, Value* other) const
 57Value* Const32Value::subConstant(Procedure& proc, const Value* other) const
5858{
5959 if (!other->hasInt32())
6060 return nullptr;
6161 return proc.add<Const32Value>(origin(), m_value - other->asInt32());
6262}
6363
64 Value* Const32Value::bitAndConstant(Procedure& proc, Value* other) const
 64Value* Const32Value::divConstant(Procedure& proc, const Value* other) const
 65{
 66 if (!other->hasInt32())
 67 return nullptr;
 68 return proc.add<Const32Value>(origin(), chillDiv(m_value, other->asInt32()));
 69}
 70
 71Value* Const32Value::bitAndConstant(Procedure& proc, const Value* other) const
6572{
6673 if (!other->hasInt32())
6774 return nullptr;
6875 return proc.add<Const32Value>(origin(), m_value & other->asInt32());
6976}
7077
71 Value* Const32Value::bitOrConstant(Procedure& proc, Value* other) const
 78Value* Const32Value::bitOrConstant(Procedure& proc, const Value* other) const
7279{
7380 if (!other->hasInt32())
7481 return nullptr;
7582 return proc.add<Const32Value>(origin(), m_value | other->asInt32());
7683}
7784
78 Value* Const32Value::bitXorConstant(Procedure& proc, Value* other) const
 85Value* Const32Value::bitXorConstant(Procedure& proc, const Value* other) const
7986{
8087 if (!other->hasInt32())
8188 return nullptr;
8289 return proc.add<Const32Value>(origin(), m_value ^ other->asInt32());
8390}
8491
85 Value* Const32Value::shlConstant(Procedure& proc, Value* other) const
 92Value* Const32Value::shlConstant(Procedure& proc, const Value* other) const
8693{
8794 if (!other->hasInt32())
8895 return nullptr;
8996 return proc.add<Const32Value>(origin(), m_value << (other->asInt32() & 31));
9097}
9198
92 Value* Const32Value::sShrConstant(Procedure& proc, Value* other) const
 99Value* Const32Value::sShrConstant(Procedure& proc, const Value* other) const
93100{
94101 if (!other->hasInt32())
95102 return nullptr;
96103 return proc.add<Const32Value>(origin(), m_value >> (other->asInt32() & 31));
97104}
98105
99 Value* Const32Value::zShrConstant(Procedure& proc, Value* other) const
 106Value* Const32Value::zShrConstant(Procedure& proc, const Value* other) const
100107{
101108 if (!other->hasInt32())
102109 return nullptr;
103110 return proc.add<Const32Value>(origin(), static_cast<int32_t>(static_cast<uint32_t>(m_value) >> (other->asInt32() & 31)));
104111}
105112
106 TriState Const32Value::equalConstant(Value* other) const
 113TriState Const32Value::equalConstant(const Value* other) const
107114{
108115 if (!other->hasInt32())
109116 return MixedTriState;
110117 return triState(m_value == other->asInt32());
111118}
112119
113 TriState Const32Value::notEqualConstant(Value* other) const
 120TriState Const32Value::notEqualConstant(const Value* other) const
114121{
115122 if (!other->hasInt32())
116123 return MixedTriState;
117124 return triState(m_value != other->asInt32());
118125}
119126
120 TriState Const32Value::lessThanConstant(Value* other) const
 127TriState Const32Value::lessThanConstant(const Value* other) const
121128{
122129 if (!other->hasInt32())
123130 return MixedTriState;
124131 return triState(m_value < other->asInt32());
125132}
126133
127 TriState Const32Value::greaterThanConstant(Value* other) const
 134TriState Const32Value::greaterThanConstant(const Value* other) const
128135{
129136 if (!other->hasInt32())
130137 return MixedTriState;
131138 return triState(m_value > other->asInt32());
132139}
133140
134 TriState Const32Value::lessEqualConstant(Value* other) const
 141TriState Const32Value::lessEqualConstant(const Value* other) const
135142{
136143 if (!other->hasInt32())
137144 return MixedTriState;
138145 return triState(m_value <= other->asInt32());
139146}
140147
141 TriState Const32Value::greaterEqualConstant(Value* other) const
 148TriState Const32Value::greaterEqualConstant(const Value* other) const
142149{
143150 if (!other->hasInt32())
144151 return MixedTriState;
145152 return triState(m_value >= other->asInt32());
146153}
147154
148 TriState Const32Value::aboveConstant(Value* other) const
 155TriState Const32Value::aboveConstant(const Value* other) const
149156{
150157 if (!other->hasInt32())
151158 return MixedTriState;
152159 return triState(static_cast<uint32_t>(m_value) > static_cast<uint32_t>(other->asInt32()));
153160}
154161
155 TriState Const32Value::belowConstant(Value* other) const
 162TriState Const32Value::belowConstant(const Value* other) const
156163{
157164 if (!other->hasInt32())
158165 return MixedTriState;
159166 return triState(static_cast<uint32_t>(m_value) < static_cast<uint32_t>(other->asInt32()));
160167}
161168
162 TriState Const32Value::aboveEqualConstant(Value* other) const
 169TriState Const32Value::aboveEqualConstant(const Value* other) const
163170{
164171 if (!other->hasInt32())
165172 return MixedTriState;
166173 return triState(static_cast<uint32_t>(m_value) >= static_cast<uint32_t>(other->asInt32()));
167174}
168175
169 TriState Const32Value::belowEqualConstant(Value* other) const
 176TriState Const32Value::belowEqualConstant(const Value* other) const
170177{
171178 if (!other->hasInt32())
172179 return MixedTriState;
192259

Source/JavaScriptCore/b3/B3Const32Value.h

@@public:
4242
4343 Value* negConstant(Procedure&) const override;
4444 Value* addConstant(Procedure&, int32_t other) const override;
45  Value* addConstant(Procedure&, Value* other) const override;
46  Value* subConstant(Procedure&, Value* other) const override;
47  Value* bitAndConstant(Procedure&, Value* other) const override;
48  Value* bitOrConstant(Procedure&, Value* other) const override;
49  Value* bitXorConstant(Procedure&, Value* other) const override;
50  Value* shlConstant(Procedure&, Value* other) const override;
51  Value* sShrConstant(Procedure&, Value* other) const override;
52  Value* zShrConstant(Procedure&, Value* other) const override;
53 
54  TriState equalConstant(Value* other) const override;
55  TriState notEqualConstant(Value* other) const override;
56  TriState lessThanConstant(Value* other) const override;
57  TriState greaterThanConstant(Value* other) const override;
58  TriState lessEqualConstant(Value* other) const override;
59  TriState greaterEqualConstant(Value* other) const override;
60  TriState aboveConstant(Value* other) const override;
61  TriState belowConstant(Value* other) const override;
62  TriState aboveEqualConstant(Value* other) const override;
63  TriState belowEqualConstant(Value* other) const override;
 45 Value* addConstant(Procedure&, const Value* other) const override;
 46 Value* subConstant(Procedure&, const Value* other) const override;
 47 Value* divConstant(Procedure&, const Value* other) const override;
 48 Value* bitAndConstant(Procedure&, const Value* other) const override;
 49 Value* bitOrConstant(Procedure&, const Value* other) const override;
 50 Value* bitXorConstant(Procedure&, const Value* other) const override;
 51 Value* shlConstant(Procedure&, const Value* other) const override;
 52 Value* sShrConstant(Procedure&, const Value* other) const override;
 53 Value* zShrConstant(Procedure&, const Value* other) const override;
 54
 55 TriState equalConstant(const Value* other) const override;
 56 TriState notEqualConstant(const Value* other) const override;
 57 TriState lessThanConstant(const Value* other) const override;
 58 TriState greaterThanConstant(const Value* other) const override;
 59 TriState lessEqualConstant(const Value* other) const override;
 60 TriState greaterEqualConstant(const Value* other) const override;
 61 TriState aboveConstant(const Value* other) const override;
 62 TriState belowConstant(const Value* other) const override;
 63 TriState aboveEqualConstant(const Value* other) const override;
 64 TriState belowEqualConstant(const Value* other) const override;
6465
6566protected:
6667 JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
192259

Source/JavaScriptCore/b3/B3Const64Value.cpp

@@Value* Const64Value::addConstant(Procedu
4747 return proc.add<Const64Value>(origin(), m_value + static_cast<int64_t>(other));
4848}
4949
50 Value* Const64Value::addConstant(Procedure& proc, Value* other) const
 50Value* Const64Value::addConstant(Procedure& proc, const Value* other) const
5151{
5252 if (!other->hasInt64())
5353 return nullptr;
5454 return proc.add<Const64Value>(origin(), m_value + other->asInt64());
5555}
5656
57 Value* Const64Value::subConstant(Procedure& proc, Value* other) const
 57Value* Const64Value::subConstant(Procedure& proc, const Value* other) const
5858{
5959 if (!other->hasInt64())
6060 return nullptr;
6161 return proc.add<Const64Value>(origin(), m_value - other->asInt64());
6262}
6363
64 Value* Const64Value::bitAndConstant(Procedure& proc, Value* other) const
 64Value* Const64Value::divConstant(Procedure& proc, const Value* other) const
 65{
 66 if (!other->hasInt64())
 67 return nullptr;
 68 return proc.add<Const64Value>(origin(), chillDiv(m_value, other->asInt64()));
 69}
 70
 71Value* Const64Value::bitAndConstant(Procedure& proc, const Value* other) const
6572{
6673 if (!other->hasInt64())
6774 return nullptr;
6875 return proc.add<Const64Value>(origin(), m_value & other->asInt64());
6976}
7077
71 Value* Const64Value::bitOrConstant(Procedure& proc, Value* other) const
 78Value* Const64Value::bitOrConstant(Procedure& proc, const Value* other) const
7279{
7380 if (!other->hasInt64())
7481 return nullptr;
7582 return proc.add<Const64Value>(origin(), m_value | other->asInt64());
7683}
7784
78 Value* Const64Value::bitXorConstant(Procedure& proc, Value* other) const
 85Value* Const64Value::bitXorConstant(Procedure& proc, const Value* other) const
7986{
8087 if (!other->hasInt64())
8188 return nullptr;
8289 return proc.add<Const64Value>(origin(), m_value ^ other->asInt64());
8390}
8491
85 Value* Const64Value::shlConstant(Procedure& proc, Value* other) const
 92Value* Const64Value::shlConstant(Procedure& proc, const Value* other) const
8693{
8794 if (!other->hasInt32())
8895 return nullptr;
8996 return proc.add<Const64Value>(origin(), m_value << (other->asInt32() & 63));
9097}
9198
92 Value* Const64Value::sShrConstant(Procedure& proc, Value* other) const
 99Value* Const64Value::sShrConstant(Procedure& proc, const Value* other) const
93100{
94101 if (!other->hasInt32())
95102 return nullptr;
96103 return proc.add<Const64Value>(origin(), m_value >> (other->asInt32() & 63));
97104}
98105
99 Value* Const64Value::zShrConstant(Procedure& proc, Value* other) const
 106Value* Const64Value::zShrConstant(Procedure& proc, const Value* other) const
100107{
101108 if (!other->hasInt32())
102109 return nullptr;
103110 return proc.add<Const64Value>(origin(), static_cast<int64_t>(static_cast<uint64_t>(m_value) >> (other->asInt32() & 63)));
104111}
105112
106 TriState Const64Value::equalConstant(Value* other) const
 113TriState Const64Value::equalConstant(const Value* other) const
107114{
108115 if (!other->hasInt64())
109116 return MixedTriState;
110117 return triState(m_value == other->asInt64());
111118}
112119
113 TriState Const64Value::notEqualConstant(Value* other) const
 120TriState Const64Value::notEqualConstant(const Value* other) const
114121{
115122 if (!other->hasInt64())
116123 return MixedTriState;
117124 return triState(m_value != other->asInt64());
118125}
119126
120 TriState Const64Value::lessThanConstant(Value* other) const
 127TriState Const64Value::lessThanConstant(const Value* other) const
121128{
122129 if (!other->hasInt64())
123130 return MixedTriState;
124131 return triState(m_value < other->asInt64());
125132}
126133
127 TriState Const64Value::greaterThanConstant(Value* other) const
 134TriState Const64Value::greaterThanConstant(const Value* other) const
128135{
129136 if (!other->hasInt64())
130137 return MixedTriState;
131138 return triState(m_value > other->asInt64());
132139}
133140
134 TriState Const64Value::lessEqualConstant(Value* other) const
 141TriState Const64Value::lessEqualConstant(const Value* other) const
135142{
136143 if (!other->hasInt64())
137144 return MixedTriState;
138145 return triState(m_value <= other->asInt64());
139146}
140147
141 TriState Const64Value::greaterEqualConstant(Value* other) const
 148TriState Const64Value::greaterEqualConstant(const Value* other) const
142149{
143150 if (!other->hasInt64())
144151 return MixedTriState;
145152 return triState(m_value >= other->asInt64());
146153}
147154
148 TriState Const64Value::aboveConstant(Value* other) const
 155TriState Const64Value::aboveConstant(const Value* other) const
149156{
150157 if (!other->hasInt64())
151158 return MixedTriState;
152159 return triState(static_cast<uint64_t>(m_value) > static_cast<uint64_t>(other->asInt64()));
153160}
154161
155 TriState Const64Value::belowConstant(Value* other) const
 162TriState Const64Value::belowConstant(const Value* other) const
156163{
157164 if (!other->hasInt64())
158165 return MixedTriState;
159166 return triState(static_cast<uint64_t>(m_value) < static_cast<uint64_t>(other->asInt64()));
160167}
161168
162 TriState Const64Value::aboveEqualConstant(Value* other) const
 169TriState Const64Value::aboveEqualConstant(const Value* other) const
163170{
164171 if (!other->hasInt64())
165172 return MixedTriState;
166173 return triState(static_cast<uint64_t>(m_value) >= static_cast<uint64_t>(other->asInt64()));
167174}
168175
169 TriState Const64Value::belowEqualConstant(Value* other) const
 176TriState Const64Value::belowEqualConstant(const Value* other) const
170177{
171178 if (!other->hasInt64())
172179 return MixedTriState;
192259

Source/JavaScriptCore/b3/B3Const64Value.h

@@public:
4242
4343 Value* negConstant(Procedure&) const override;
4444 Value* addConstant(Procedure&, int32_t other) const override;
45  Value* addConstant(Procedure&, Value* other) const override;
46  Value* subConstant(Procedure&, Value* other) const override;
47  Value* bitAndConstant(Procedure&, Value* other) const override;
48  Value* bitOrConstant(Procedure&, Value* other) const override;
49  Value* bitXorConstant(Procedure&, Value* other) const override;
50  Value* shlConstant(Procedure&, Value* other) const override;
51  Value* sShrConstant(Procedure&, Value* other) const override;
52  Value* zShrConstant(Procedure&, Value* other) const override;
53 
54  TriState equalConstant(Value* other) const override;
55  TriState notEqualConstant(Value* other) const override;
56  TriState lessThanConstant(Value* other) const override;
57  TriState greaterThanConstant(Value* other) const override;
58  TriState lessEqualConstant(Value* other) const override;
59  TriState greaterEqualConstant(Value* other) const override;
60  TriState aboveConstant(Value* other) const override;
61  TriState belowConstant(Value* other) const override;
62  TriState aboveEqualConstant(Value* other) const override;
63  TriState belowEqualConstant(Value* other) const override;
 45 Value* addConstant(Procedure&, const Value* other) const override;
 46 Value* subConstant(Procedure&, const Value* other) const override;
 47 Value* divConstant(Procedure&, const Value* other) const override;
 48 Value* bitAndConstant(Procedure&, const Value* other) const override;
 49 Value* bitOrConstant(Procedure&, const Value* other) const override;
 50 Value* bitXorConstant(Procedure&, const Value* other) const override;
 51 Value* shlConstant(Procedure&, const Value* other) const override;
 52 Value* sShrConstant(Procedure&, const Value* other) const override;
 53 Value* zShrConstant(Procedure&, const Value* other) const override;
 54
 55 TriState equalConstant(const Value* other) const override;
 56 TriState notEqualConstant(const Value* other) const override;
 57 TriState lessThanConstant(const Value* other) const override;
 58 TriState greaterThanConstant(const Value* other) const override;
 59 TriState lessEqualConstant(const Value* other) const override;
 60 TriState greaterEqualConstant(const Value* other) const override;
 61 TriState aboveConstant(const Value* other) const override;
 62 TriState belowConstant(const Value* other) const override;
 63 TriState aboveEqualConstant(const Value* other) const override;
 64 TriState belowEqualConstant(const Value* other) const override;
6465
6566protected:
6667 void dumpMeta(CommaPrinter&, PrintStream&) const override;
192259

Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp

@@Value* ConstDoubleValue::addConstant(Pro
4747 return proc.add<ConstDoubleValue>(origin(), m_value + static_cast<double>(other));
4848}
4949
50 Value* ConstDoubleValue::addConstant(Procedure& proc, Value* other) const
 50Value* ConstDoubleValue::addConstant(Procedure& proc, const Value* other) const
5151{
5252 if (!other->hasDouble())
5353 return nullptr;
5454 return proc.add<ConstDoubleValue>(origin(), m_value + other->asDouble());
5555}
5656
57 Value* ConstDoubleValue::subConstant(Procedure& proc, Value* other) const
 57Value* ConstDoubleValue::subConstant(Procedure& proc, const Value* other) const
5858{
5959 if (!other->hasDouble())
6060 return nullptr;
6161 return proc.add<ConstDoubleValue>(origin(), m_value - other->asDouble());
6262}
6363
64 TriState ConstDoubleValue::equalConstant(Value* other) const
 64Value* ConstDoubleValue::divConstant(Procedure& proc, const Value* other) const
 65{
 66 if (!other->hasDouble())
 67 return nullptr;
 68 return proc.add<ConstDoubleValue>(origin(), m_value / other->asDouble());
 69}
 70
 71TriState ConstDoubleValue::equalConstant(const Value* other) const
6572{
6673 if (!other->hasDouble())
6774 return MixedTriState;
6875 return triState(m_value == other->asDouble());
6976}
7077
71 TriState ConstDoubleValue::notEqualConstant(Value* other) const
 78TriState ConstDoubleValue::notEqualConstant(const Value* other) const
7279{
7380 if (!other->hasDouble())
7481 return MixedTriState;
7582 return triState(m_value != other->asDouble());
7683}
7784
78 TriState ConstDoubleValue::lessThanConstant(Value* other) const
 85TriState ConstDoubleValue::lessThanConstant(const Value* other) const
7986{
8087 if (!other->hasDouble())
8188 return MixedTriState;
8289 return triState(m_value < other->asDouble());
8390}
8491
85 TriState ConstDoubleValue::greaterThanConstant(Value* other) const
 92TriState ConstDoubleValue::greaterThanConstant(const Value* other) const
8693{
8794 if (!other->hasDouble())
8895 return MixedTriState;
8996 return triState(m_value > other->asDouble());
9097}
9198
92 TriState ConstDoubleValue::lessEqualConstant(Value* other) const
 99TriState ConstDoubleValue::lessEqualConstant(const Value* other) const
93100{
94101 if (!other->hasDouble())
95102 return MixedTriState;
96103 return triState(m_value <= other->asDouble());
97104}
98105
99 TriState ConstDoubleValue::greaterEqualConstant(Value* other) const
 106TriState ConstDoubleValue::greaterEqualConstant(const Value* other) const
100107{
101108 if (!other->hasDouble())
102109 return MixedTriState;
192259

Source/JavaScriptCore/b3/B3ConstDoubleValue.h

@@public:
4242
4343 Value* negConstant(Procedure& proc) const override;
4444 Value* addConstant(Procedure& proc, int32_t other) const override;
45  Value* addConstant(Procedure& proc, Value* other) const override;
46  Value* subConstant(Procedure& proc, Value* other) const override;
47 
48  TriState equalConstant(Value* other) const override;
49  TriState notEqualConstant(Value* other) const override;
50  TriState lessThanConstant(Value* other) const override;
51  TriState greaterThanConstant(Value* other) const override;
52  TriState lessEqualConstant(Value* other) const override;
53  TriState greaterEqualConstant(Value* other) const override;
 45 Value* addConstant(Procedure& proc, const Value* other) const override;
 46 Value* subConstant(Procedure& proc, const Value* other) const override;
 47 Value* divConstant(Procedure& proc, const Value* other) const override;
 48
 49 TriState equalConstant(const Value* other) const override;
 50 TriState notEqualConstant(const Value* other) const override;
 51 TriState lessThanConstant(const Value* other) const override;
 52 TriState greaterThanConstant(const Value* other) const override;
 53 TriState lessEqualConstant(const Value* other) const override;
 54 TriState greaterEqualConstant(const Value* other) const override;
5455
5556protected:
5657 void dumpMeta(CommaPrinter&, PrintStream&) const override;
192259

Source/JavaScriptCore/b3/B3Generate.cpp

3232#include "AirGenerate.h"
3333#include "AirInstInlines.h"
3434#include "B3Common.h"
 35#include "B3LowerMacros.h"
3536#include "B3LowerToAir.h"
3637#include "B3MoveConstants.h"
3738#include "B3Procedure.h"

@@void generateToAir(Procedure& procedure,
6667 dataLog(procedure);
6768 }
6869
 70 lowerMacros(procedure);
 71
6972 reduceStrength(procedure);
7073
7174 // FIXME: Add more optimizations here.
192259

Source/JavaScriptCore/b3/B3InsertionSet.cpp

2929#if ENABLE(B3_JIT)
3030
3131#include "B3BasicBlock.h"
 32#include "B3ProcedureInlines.h"
 33#include "B3ValueInlines.h"
3234#include <wtf/BubbleSort.h>
3335
3436namespace JSC { namespace B3 {
3537
 38Value* InsertionSet::insertIntConstant(size_t index, Origin origin, Type type, int64_t value)
 39{
 40 return insertValue(index, m_procedure.addIntConstant(origin, type, value));
 41}
 42
 43Value* InsertionSet::insertIntConstant(size_t index, Value* likeValue, int64_t value)
 44{
 45 return insertIntConstant(index, likeValue->origin(), likeValue->type(), value);
 46}
 47
3648void InsertionSet::execute(BasicBlock* block)
3749{
3850 bubbleSort(m_insertions.begin(), m_insertions.end());
192259

Source/JavaScriptCore/b3/B3InsertionSet.h

2828
2929#if ENABLE(B3_JIT)
3030
 31#include "B3Origin.h"
 32#include "B3Type.h"
3133#include <wtf/Insertion.h>
3234#include <wtf/Vector.h>
3335

@@public:
6264 template<typename ValueType, typename... Arguments>
6365 Value* insert(size_t index, Arguments... arguments);
6466
 67 Value* insertIntConstant(size_t index, Origin, Type, int64_t value);
 68 Value* insertIntConstant(size_t index, Value* likeValue, int64_t value);
 69
6570 void execute(BasicBlock*);
6671
6772private:
192259

Source/JavaScriptCore/b3/B3LowerMacros.cpp

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "B3LowerMacros.h"
 28
 29#if ENABLE(B3_JIT)
 30
 31#include "B3BasicBlockInlines.h"
 32#include "B3BlockInsertionSet.h"
 33#include "B3ControlValue.h"
 34#include "B3InsertionSetInlines.h"
 35#include "B3PhaseScope.h"
 36#include "B3ProcedureInlines.h"
 37#include "B3UpsilonValue.h"
 38#include "B3ValueInlines.h"
 39
 40namespace JSC { namespace B3 {
 41
 42namespace {
 43
 44class LowerMacros {
 45public:
 46 LowerMacros(Procedure& proc)
 47 : m_proc(proc)
 48 , m_blockInsertionSet(proc)
 49 , m_insertionSet(proc)
 50 {
 51 }
 52
 53 bool run()
 54 {
 55 for (BasicBlock* block : m_proc) {
 56 m_block = block;
 57 processCurrentBlock();
 58 }
 59 m_changed |= m_blockInsertionSet.execute();
 60 if (m_changed)
 61 m_proc.resetReachability();
 62 return m_changed;
 63 }
 64
 65private:
 66 void processCurrentBlock()
 67 {
 68 for (m_index = 0; m_index < m_block->size(); ++m_index) {
 69 m_value = m_block->at(m_index);
 70 switch (m_value->opcode()) {
 71 case ChillDiv: {
 72 // ARM supports this instruction natively.
 73 if (isARM64())
 74 break;
 75
 76 m_changed = true;
 77
 78 // We implement "res = ChillDiv(num, den)" as follows:
 79 //
 80 // if (den + 1 <=_unsigned 1) {
 81 // if (!den) {
 82 // res = 0;
 83 // goto done;
 84 // }
 85 // if (num == -2147483648) {
 86 // res = num;
 87 // goto done;
 88 // }
 89 // }
 90 // res = num / dev;
 91 // done:
 92
 93 Value* num = m_value->child(0);
 94 Value* den = m_value->child(1);
 95
 96 Value* one =
 97 m_insertionSet.insertIntConstant(m_index, m_value, 1);
 98 Value* isDenOK = m_insertionSet.insert<Value>(
 99 m_index, Above, m_value->origin(),
 100 m_insertionSet.insert<Value>(m_index, Add, m_value->origin(), den, one),
 101 one);
 102
 103 BasicBlock* before =
 104 m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet);
 105
 106 BasicBlock* normalDivCase = m_blockInsertionSet.insertBefore(m_block);
 107 BasicBlock* shadyDenCase = m_blockInsertionSet.insertBefore(m_block);
 108 BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block);
 109 BasicBlock* neg1DenCase = m_blockInsertionSet.insertBefore(m_block);
 110 BasicBlock* intMinCase = m_blockInsertionSet.insertBefore(m_block);
 111
 112 before->replaceLastWithNew<ControlValue>(
 113 m_proc, Branch, m_value->origin(), isDenOK,
 114 FrequentedBlock(normalDivCase, FrequencyClass::Normal),
 115 FrequentedBlock(shadyDenCase, FrequencyClass::Rare));
 116
 117 UpsilonValue* normalResult = normalDivCase->appendNew<UpsilonValue>(
 118 m_proc, m_value->origin(),
 119 normalDivCase->appendNew<Value>(m_proc, Div, m_value->origin(), num, den));
 120 normalDivCase->appendNew<ControlValue>(
 121 m_proc, Jump, m_value->origin(), FrequentedBlock(m_block));
 122
 123 shadyDenCase->appendNew<ControlValue>(
 124 m_proc, Branch, m_value->origin(), den,
 125 FrequentedBlock(neg1DenCase, FrequencyClass::Normal),
 126 FrequentedBlock(zeroDenCase, FrequencyClass::Rare));
 127
 128 UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>(
 129 m_proc, m_value->origin(),
 130 zeroDenCase->appendIntConstant(m_proc, m_value, 0));
 131 zeroDenCase->appendNew<ControlValue>(
 132 m_proc, Jump, m_value->origin(), FrequentedBlock(m_block));
 133
 134 int64_t badNumeratorConst;
 135 switch (m_value->type()) {
 136 case Int32:
 137 badNumeratorConst = -2147483647 - 1;
 138 break;
 139 case Int64:
 140 badNumeratorConst = -9223372036854775807ll - 1;
 141 break;
 142 default:
 143 ASSERT_NOT_REACHED();
 144 badNumeratorConst = 0;
 145 }
 146
 147 Value* badNumerator =
 148 neg1DenCase->appendIntConstant(m_proc, m_value, badNumeratorConst);
 149
 150 neg1DenCase->appendNew<ControlValue>(
 151 m_proc, Branch, m_value->origin(),
 152 neg1DenCase->appendNew<Value>(
 153 m_proc, Equal, m_value->origin(), num, badNumerator),
 154 FrequentedBlock(intMinCase, FrequencyClass::Rare),
 155 FrequentedBlock(normalDivCase, FrequencyClass::Normal));
 156
 157 UpsilonValue* intMinResult = intMinCase->appendNew<UpsilonValue>(
 158 m_proc, m_value->origin(), badNumerator);
 159 intMinCase->appendNew<ControlValue>(
 160 m_proc, Jump, m_value->origin(), FrequentedBlock(m_block));
 161
 162 Value* phi = m_insertionSet.insert<Value>(
 163 m_index, Phi, m_value->type(), m_value->origin());
 164 normalResult->setPhi(phi);
 165 zeroResult->setPhi(phi);
 166 intMinResult->setPhi(phi);
 167
 168 m_value->replaceWithIdentity(phi);
 169 break;
 170 }
 171
 172 // FIXME: Implement Switch.
 173 // https://bugs.webkit.org/show_bug.cgi?id=151115
 174
 175 default:
 176 break;
 177 }
 178 }
 179 m_insertionSet.execute(m_block);
 180 }
 181
 182 Procedure& m_proc;
 183 BlockInsertionSet m_blockInsertionSet;
 184 InsertionSet m_insertionSet;
 185 BasicBlock* m_block;
 186 unsigned m_index;
 187 Value* m_value;
 188 bool m_changed { false };
 189};
 190
 191} // anonymous namespace
 192
 193bool lowerMacros(Procedure& proc)
 194{
 195 PhaseScope phaseScope(proc, "lowerMacros");
 196 LowerMacros lowerMacros(proc);
 197 return lowerMacros.run();
 198}
 199
 200} } // namespace JSC::B3
 201
 202#endif // ENABLE(B3_JIT)
 203
0

Source/JavaScriptCore/b3/B3LowerMacros.h

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef B3LowerMacros_h
 27#define B3LowerMacros_h
 28
 29#if ENABLE(B3_JIT)
 30
 31namespace JSC { namespace B3 {
 32
 33class Procedure;
 34
 35// Lowers high-level operations that it's easier to deal with once they are broken up. Currently
 36// this includes Switch and ChillDiv.
 37
 38bool lowerMacros(Procedure&);
 39
 40} } // namespace JSC::B3
 41
 42#endif // ENABLE(B3_JIT)
 43
 44#endif // B3LowerMacros_h
 45
0

Source/JavaScriptCore/b3/B3LowerToAir.cpp

@@private:
12331233 return;
12341234 }
12351235
 1236 case Div: {
 1237 if (isInt(m_value->type())) {
 1238 Tmp eax = Tmp(X86Registers::eax);
 1239 Tmp edx = Tmp(X86Registers::edx);
 1240
 1241 Air::Opcode convertToDoubleWord;
 1242 Air::Opcode div;
 1243 switch (m_value->type()) {
 1244 case Int32:
 1245 convertToDoubleWord = X86ConvertToDoubleWord32;
 1246 div = X86Div32;
 1247 break;
 1248 case Int64:
 1249 convertToDoubleWord = X86ConvertToDoubleWord64;
 1250 div = X86Div64;
 1251 break;
 1252 default:
 1253 RELEASE_ASSERT_NOT_REACHED();
 1254 return;
 1255 }
 1256
 1257 append(Move, tmp(m_value->child(0)), eax);
 1258 append(convertToDoubleWord, eax, edx);
 1259 append(div, eax, edx, tmp(m_value->child(1)));
 1260 append(Move, eax, tmp(m_value));
 1261 return;
 1262 }
 1263
 1264 // FIXME: Support doubles.
 1265 // https://bugs.webkit.org/show_bug.cgi?id=150991
 1266 RELEASE_ASSERT_NOT_REACHED();
 1267 return;
 1268 }
 1269
12361270 case BitAnd: {
12371271 appendBinOp<And32, And64, Air::Oops, Commutative>(
12381272 m_value->child(0), m_value->child(1));
192259

Source/JavaScriptCore/b3/B3Opcode.h

@@enum Opcode : int16_t {
6969 Add,
7070 Sub,
7171 Mul,
72  Div,
 72 Div, // All bets are off as to what will happen when you execute this for -2^31/-1 and x/0.
7373
7474 // Integer math.
7575 ChillDiv, // doesn't trap ever, behaves like JS (x/y)|0.
192259

Source/JavaScriptCore/b3/B3Procedure.cpp

@@BasicBlock* Procedure::addBlock(double f
5555 return result;
5656}
5757
58 Value* Procedure::addIntConstant(Type type, int64_t value)
 58Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
5959{
6060 switch (type) {
6161 case Int32:
62  return add<Const32Value>(Origin(), static_cast<int32_t>(value));
 62 return add<Const32Value>(origin, static_cast<int32_t>(value));
6363 case Int64:
64  return add<Const64Value>(Origin(), value);
 64 return add<Const64Value>(origin, value);
6565 case Double:
66  return add<ConstDoubleValue>(Origin(), static_cast<double>(value));
 66 return add<ConstDoubleValue>(origin, static_cast<double>(value));
6767 default:
6868 RELEASE_ASSERT_NOT_REACHED();
6969 return nullptr;
7070 }
7171}
7272
73 Value* Procedure::addBoolConstant(TriState triState)
 73Value* Procedure::addIntConstant(Value* likeValue, int64_t value)
 74{
 75 return addIntConstant(likeValue->origin(), likeValue->type(), value);
 76}
 77
 78Value* Procedure::addBoolConstant(Origin origin, TriState triState)
7479{
7580 int32_t value = 0;
7681 switch (triState) {

@@Value* Procedure::addBoolConstant(TriSta
8489 return nullptr;
8590 }
8691
87  return addIntConstant(Int32, value);
 92 return addIntConstant(origin, Int32, value);
8893}
8994
9095void Procedure::resetValueOwners()
192259

Source/JavaScriptCore/b3/B3Procedure.h

2828
2929#if ENABLE(B3_JIT)
3030
 31#include "B3Origin.h"
3132#include "B3Type.h"
3233#include "PureNaN.h"
3334#include <wtf/Bag.h>

4041namespace JSC { namespace B3 {
4142
4243class BasicBlock;
 44class BlockInsertionSet;
4345class OpaqueByproducts;
4446class Value;
4547

@@public:
5658 template<typename ValueType, typename... Arguments>
5759 ValueType* add(Arguments...);
5860
59  Value* addIntConstant(Type, int64_t value);
 61 Value* addIntConstant(Origin, Type, int64_t value);
 62 Value* addIntConstant(Value*, int64_t value);
6063
6164 // Returns null for MixedTriState.
62  Value* addBoolConstant(TriState);
 65 Value* addBoolConstant(Origin, TriState);
6366
6467 void resetValueOwners();
6568 void resetReachability();

@@public:
216219 std::unique_ptr<OpaqueByproducts> takeByproducts() { return WTF::move(m_byproducts); }
217220
218221private:
 222 friend class BlockInsertionSet;
 223
219224 JS_EXPORT_PRIVATE size_t addValueIndex();
220225
221226 Vector<std::unique_ptr<BasicBlock>> m_blocks;
192259

Source/JavaScriptCore/b3/B3ReduceStrength.cpp

@@private:
186186
187187 break;
188188
 189 case Div:
 190 case ChillDiv:
 191 // Turn this: Div(constant1, constant2)
 192 // Into this: constant1 / constant2
 193 // Note that this uses ChillDiv semantics. That's fine, because the rules for Div
 194 // are strictly weaker: it has corner cases where it's allowed to do anything it
 195 // likes.
 196 replaceWithNewValue(m_value->child(0)->divConstant(m_proc, m_value->child(1)));
 197 break;
 198
189199 case BitAnd:
190200 handleCommutativity();
191201

@@private:
318328 // Turn this: BitXor(valueX, valueX)
319329 // Into this: zero-constant.
320330 if (m_value->child(0) == m_value->child(1)) {
321  replaceWithNewValue(m_proc.addIntConstant(m_value->type(), 0));
 331 replaceWithNewValue(m_proc.addIntConstant(m_value, 0));
322332 break;
323333 }
324334

@@private:
446456 // Turn this: Equal(const1, const2)
447457 // Into this: const1 == const2
448458 replaceWithNewValue(
449  m_proc.addBoolConstant(m_value->child(0)->equalConstant(m_value->child(1))));
 459 m_proc.addBoolConstant(
 460 m_value->origin(),
 461 m_value->child(0)->equalConstant(m_value->child(1))));
450462 break;
451463
452464 case NotEqual:

@@private:
473485 // Turn this: NotEqual(const1, const2)
474486 // Into this: const1 != const2
475487 replaceWithNewValue(
476  m_proc.addBoolConstant(m_value->child(0)->notEqualConstant(m_value->child(1))));
 488 m_proc.addBoolConstant(
 489 m_value->origin(),
 490 m_value->child(0)->notEqualConstant(m_value->child(1))));
477491 break;
478492
479493 case LessThan:

@@private:
481495 // https://bugs.webkit.org/show_bug.cgi?id=150958
482496
483497 replaceWithNewValue(
484  m_proc.addBoolConstant(m_value->child(0)->lessThanConstant(m_value->child(1))));
 498 m_proc.addBoolConstant(
 499 m_value->origin(),
 500 m_value->child(0)->lessThanConstant(m_value->child(1))));
485501 break;
486502
487503 case GreaterThan:
488504 replaceWithNewValue(
489  m_proc.addBoolConstant(m_value->child(0)->greaterThanConstant(m_value->child(1))));
 505 m_proc.addBoolConstant(
 506 m_value->origin(),
 507 m_value->child(0)->greaterThanConstant(m_value->child(1))));
490508 break;
491509
492510 case LessEqual:
493511 replaceWithNewValue(
494  m_proc.addBoolConstant(m_value->child(0)->lessEqualConstant(m_value->child(1))));
 512 m_proc.addBoolConstant(
 513 m_value->origin(),
 514 m_value->child(0)->lessEqualConstant(m_value->child(1))));
495515 break;
496516
497517 case GreaterEqual:
498518 replaceWithNewValue(
499  m_proc.addBoolConstant(m_value->child(0)->greaterEqualConstant(m_value->child(1))));
 519 m_proc.addBoolConstant(
 520 m_value->origin(),
 521 m_value->child(0)->greaterEqualConstant(m_value->child(1))));
500522 break;
501523
502524 case Above:
503525 replaceWithNewValue(
504  m_proc.addBoolConstant(m_value->child(0)->aboveConstant(m_value->child(1))));
 526 m_proc.addBoolConstant(
 527 m_value->origin(),
 528 m_value->child(0)->aboveConstant(m_value->child(1))));
505529 break;
506530
507531 case Below:
508532 replaceWithNewValue(
509  m_proc.addBoolConstant(m_value->child(0)->belowConstant(m_value->child(1))));
 533 m_proc.addBoolConstant(
 534 m_value->origin(),
 535 m_value->child(0)->belowConstant(m_value->child(1))));
510536 break;
511537
512538 case AboveEqual:
513539 replaceWithNewValue(
514  m_proc.addBoolConstant(m_value->child(0)->aboveEqualConstant(m_value->child(1))));
 540 m_proc.addBoolConstant(
 541 m_value->origin(),
 542 m_value->child(0)->aboveEqualConstant(m_value->child(1))));
515543 break;
516544
517545 case BelowEqual:
518546 replaceWithNewValue(
519  m_proc.addBoolConstant(m_value->child(0)->belowEqualConstant(m_value->child(1))));
 547 m_proc.addBoolConstant(
 548 m_value->origin(),
 549 m_value->child(0)->belowEqualConstant(m_value->child(1))));
520550 break;
521551
522552 case Branch: {
192259

Source/JavaScriptCore/b3/B3Validate.cpp

@@public:
8080 }
8181
8282 for (Value* value : valueInProc) {
83  for (Value* child : value->children())
 83 for (Value* child : value->children()) {
 84 VALIDATE(child, ("At ", *value));
8485 VALIDATE(valueInProc.contains(child), ("At ", *value, "->", pointerDump(child)));
 86 }
8587 }
8688
8789 HashMap<BasicBlock*, HashSet<BasicBlock*>> allPredecessors;
192259

Source/JavaScriptCore/b3/B3Value.cpp

@@Value* Value::addConstant(Procedure&, in
124124 return nullptr;
125125}
126126
127 Value* Value::addConstant(Procedure&, Value*) const
 127Value* Value::addConstant(Procedure&, const Value*) const
128128{
129129 return nullptr;
130130}
131131
132 Value* Value::subConstant(Procedure&, Value*) const
 132Value* Value::subConstant(Procedure&, const Value*) const
133133{
134134 return nullptr;
135135}
136136
137 Value* Value::bitAndConstant(Procedure&, Value*) const
 137Value* Value::divConstant(Procedure&, const Value*) const
138138{
139139 return nullptr;
140140}
141141
142 Value* Value::bitOrConstant(Procedure&, Value*) const
 142Value* Value::bitAndConstant(Procedure&, const Value*) const
143143{
144144 return nullptr;
145145}
146146
147 Value* Value::bitXorConstant(Procedure&, Value*) const
 147Value* Value::bitOrConstant(Procedure&, const Value*) const
148148{
149149 return nullptr;
150150}
151151
152 Value* Value::shlConstant(Procedure&, Value*) const
 152Value* Value::bitXorConstant(Procedure&, const Value*) const
153153{
154154 return nullptr;
155155}
156156
157 Value* Value::sShrConstant(Procedure&, Value*) const
 157Value* Value::shlConstant(Procedure&, const Value*) const
158158{
159159 return nullptr;
160160}
161161
162 Value* Value::zShrConstant(Procedure&, Value*) const
 162Value* Value::sShrConstant(Procedure&, const Value*) const
163163{
164164 return nullptr;
165165}
166166
167 TriState Value::equalConstant(Value*) const
 167Value* Value::zShrConstant(Procedure&, const Value*) const
 168{
 169 return nullptr;
 170}
 171
 172TriState Value::equalConstant(const Value*) const
168173{
169174 return MixedTriState;
170175}
171176
172 TriState Value::notEqualConstant(Value*) const
 177TriState Value::notEqualConstant(const Value*) const
173178{
174179 return MixedTriState;
175180}
176181
177 TriState Value::lessThanConstant(Value*) const
 182TriState Value::lessThanConstant(const Value*) const
178183{
179184 return MixedTriState;
180185}
181186
182 TriState Value::greaterThanConstant(Value*) const
 187TriState Value::greaterThanConstant(const Value*) const
183188{
184189 return MixedTriState;
185190}
186191
187 TriState Value::lessEqualConstant(Value*) const
 192TriState Value::lessEqualConstant(const Value*) const
188193{
189194 return MixedTriState;
190195}
191196
192 TriState Value::greaterEqualConstant(Value*) const
 197TriState Value::greaterEqualConstant(const Value*) const
193198{
194199 return MixedTriState;
195200}
196201
197 TriState Value::aboveConstant(Value*) const
 202TriState Value::aboveConstant(const Value*) const
198203{
199204 return MixedTriState;
200205}
201206
202 TriState Value::belowConstant(Value*) const
 207TriState Value::belowConstant(const Value*) const
203208{
204209 return MixedTriState;
205210}
206211
207 TriState Value::aboveEqualConstant(Value*) const
 212TriState Value::aboveEqualConstant(const Value*) const
208213{
209214 return MixedTriState;
210215}
211216
212 TriState Value::belowEqualConstant(Value*) const
 217TriState Value::belowEqualConstant(const Value*) const
213218{
214219 return MixedTriState;
215220}
192259

Source/JavaScriptCore/b3/B3Value.h

@@public:
111111
112112 virtual Value* negConstant(Procedure&) const;
113113 virtual Value* addConstant(Procedure&, int32_t other) const;
114  virtual Value* addConstant(Procedure&, Value* other) const;
115  virtual Value* subConstant(Procedure&, Value* other) const;
116  virtual Value* bitAndConstant(Procedure&, Value* other) const;
117  virtual Value* bitOrConstant(Procedure&, Value* other) const;
118  virtual Value* bitXorConstant(Procedure&, Value* other) const;
119  virtual Value* shlConstant(Procedure&, Value* other) const;
120  virtual Value* sShrConstant(Procedure&, Value* other) const;
121  virtual Value* zShrConstant(Procedure&, Value* other) const;
 114 virtual Value* addConstant(Procedure&, const Value* other) const;
 115 virtual Value* subConstant(Procedure&, const Value* other) const;
 116 virtual Value* divConstant(Procedure&, const Value* other) const; // This chooses ChillDiv semantics for integers.
 117 virtual Value* bitAndConstant(Procedure&, const Value* other) const;
 118 virtual Value* bitOrConstant(Procedure&, const Value* other) const;
 119 virtual Value* bitXorConstant(Procedure&, const Value* other) const;
 120 virtual Value* shlConstant(Procedure&, const Value* other) const;
 121 virtual Value* sShrConstant(Procedure&, const Value* other) const;
 122 virtual Value* zShrConstant(Procedure&, const Value* other) const;
122123
123  virtual TriState equalConstant(Value* other) const;
124  virtual TriState notEqualConstant(Value* other) const;
125  virtual TriState lessThanConstant(Value* other) const;
126  virtual TriState greaterThanConstant(Value* other) const;
127  virtual TriState lessEqualConstant(Value* other) const;
128  virtual TriState greaterEqualConstant(Value* other) const;
129  virtual TriState aboveConstant(Value* other) const;
130  virtual TriState belowConstant(Value* other) const;
131  virtual TriState aboveEqualConstant(Value* other) const;
132  virtual TriState belowEqualConstant(Value* other) const;
 124 virtual TriState equalConstant(const Value* other) const;
 125 virtual TriState notEqualConstant(const Value* other) const;
 126 virtual TriState lessThanConstant(const Value* other) const;
 127 virtual TriState greaterThanConstant(const Value* other) const;
 128 virtual TriState lessEqualConstant(const Value* other) const;
 129 virtual TriState greaterEqualConstant(const Value* other) const;
 130 virtual TriState aboveConstant(const Value* other) const;
 131 virtual TriState belowConstant(const Value* other) const;
 132 virtual TriState aboveEqualConstant(const Value* other) const;
 133 virtual TriState belowEqualConstant(const Value* other) const;
133134
134135 // If the value is a comparison then this returns the inverted form of that comparison, if
135136 // possible. It can be impossible for double comparisons, where for example LessThan and
192259

Source/JavaScriptCore/b3/testb3.cpp

@@void testCallFunctionWithHellaDoubleArgu
28362836 CHECK(compileAndRun<double>(proc) == functionWithHellaDoubleArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
28372837}
28382838
 2839void testChillDiv(int num, int den, int res)
 2840{
 2841 // Test non-constant.
 2842 {
 2843 Procedure proc;
 2844 BasicBlock* root = proc.addBlock();
 2845
 2846 root->appendNew<ControlValue>(
 2847 proc, Return, Origin(),
 2848 root->appendNew<Value>(
 2849 proc, ChillDiv, Origin(),
 2850 root->appendNew<Value>(
 2851 proc, Trunc, Origin(),
 2852 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
 2853 root->appendNew<Value>(
 2854 proc, Trunc, Origin(),
 2855 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
 2856
 2857 CHECK(compileAndRun<int>(proc, num, den) == res);
 2858 }
 2859
 2860 // Test constant.
 2861 {
 2862 Procedure proc;
 2863 BasicBlock* root = proc.addBlock();
 2864
 2865 root->appendNew<ControlValue>(
 2866 proc, Return, Origin(),
 2867 root->appendNew<Value>(
 2868 proc, ChillDiv, Origin(),
 2869 root->appendNew<Const32Value>(proc, Origin(), num),
 2870 root->appendNew<Const32Value>(proc, Origin(), den)));
 2871
 2872 CHECK(compileAndRun<int>(proc) == res);
 2873 }
 2874}
 2875
 2876void testChillDivTwice(int num1, int den1, int num2, int den2, int res)
 2877{
 2878 Procedure proc;
 2879 BasicBlock* root = proc.addBlock();
 2880
 2881 root->appendNew<ControlValue>(
 2882 proc, Return, Origin(),
 2883 root->appendNew<Value>(
 2884 proc, Add, Origin(),
 2885 root->appendNew<Value>(
 2886 proc, ChillDiv, Origin(),
 2887 root->appendNew<Value>(
 2888 proc, Trunc, Origin(),
 2889 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
 2890 root->appendNew<Value>(
 2891 proc, Trunc, Origin(),
 2892 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))),
 2893 root->appendNew<Value>(
 2894 proc, ChillDiv, Origin(),
 2895 root->appendNew<Value>(
 2896 proc, Trunc, Origin(),
 2897 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
 2898 root->appendNew<Value>(
 2899 proc, Trunc, Origin(),
 2900 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)))));
 2901
 2902 CHECK(compileAndRun<int>(proc, num1, den1, num2, den2) == res);
 2903}
 2904
 2905void testChillDiv64(int64_t num, int64_t den, int64_t res)
 2906{
 2907 if (!is64Bit())
 2908 return;
 2909
 2910 // Test non-constant.
 2911 {
 2912 Procedure proc;
 2913 BasicBlock* root = proc.addBlock();
 2914
 2915 root->appendNew<ControlValue>(
 2916 proc, Return, Origin(),
 2917 root->appendNew<Value>(
 2918 proc, ChillDiv, Origin(),
 2919 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
 2920 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
 2921
 2922 CHECK(compileAndRun<int64_t>(proc, num, den) == res);
 2923 }
 2924
 2925 // Test constant.
 2926 {
 2927 Procedure proc;
 2928 BasicBlock* root = proc.addBlock();
 2929
 2930 root->appendNew<ControlValue>(
 2931 proc, Return, Origin(),
 2932 root->appendNew<Value>(
 2933 proc, ChillDiv, Origin(),
 2934 root->appendNew<Const64Value>(proc, Origin(), num),
 2935 root->appendNew<Const64Value>(proc, Origin(), den)));
 2936
 2937 CHECK(compileAndRun<int64_t>(proc) == res);
 2938 }
 2939}
 2940
28392941#define RUN(test) do { \
28402942 if (!shouldRun(#test)) \
28412943 break; \

@@void run(const char* filter)
33123414 RUN(testCallSimpleDouble(1, 2));
33133415 RUN(testCallFunctionWithHellaDoubleArguments());
33143416
 3417 RUN(testChillDiv(4, 2, 2));
 3418 RUN(testChillDiv(1, 0, 0));
 3419 RUN(testChillDiv(0, 0, 0));
 3420 RUN(testChillDiv(1, -1, -1));
 3421 RUN(testChillDiv(-2147483647 - 1, 0, 0));
 3422 RUN(testChillDiv(-2147483647 - 1, 1, -2147483647 - 1));
 3423 RUN(testChillDiv(-2147483647 - 1, -1, -2147483647 - 1));
 3424 RUN(testChillDiv(-2147483647 - 1, 2, -1073741824));
 3425 RUN(testChillDiv64(4, 2, 2));
 3426 RUN(testChillDiv64(1, 0, 0));
 3427 RUN(testChillDiv64(0, 0, 0));
 3428 RUN(testChillDiv64(1, -1, -1));
 3429 RUN(testChillDiv64(-9223372036854775807ll - 1, 0, 0));
 3430 RUN(testChillDiv64(-9223372036854775807ll - 1, 1, -9223372036854775807ll - 1));
 3431 RUN(testChillDiv64(-9223372036854775807ll - 1, -1, -9223372036854775807ll - 1));
 3432 RUN(testChillDiv64(-9223372036854775807ll - 1, 2, -4611686018427387904));
 3433 RUN(testChillDivTwice(4, 2, 6, 2, 5));
 3434 RUN(testChillDivTwice(4, 0, 6, 2, 3));
 3435 RUN(testChillDivTwice(4, 2, 6, 0, 2));
 3436
33153437 if (tasks.isEmpty())
33163438 usage();
33173439
192259

Source/JavaScriptCore/b3/air/AirInstInlines.h

@@inline bool isUrshift64Valid(const Inst&
128128 return isShiftValid(inst);
129129}
130130
 131inline bool isX86DivHelperValid(const Inst& inst)
 132{
 133#if CPU(X86) || CPU(X86_64)
 134 return inst.args[0] == Tmp(X86Registers::eax)
 135 && inst.args[1] == Tmp(X86Registers::edx);
 136#else
 137 return false;
 138#endif
 139}
 140
 141inline bool isX86ConvertToDoubleWord32Valid(const Inst& inst)
 142{
 143 return isX86DivHelperValid(inst);
 144}
 145
 146inline bool isX86ConvertToDoubleWord64Valid(const Inst& inst)
 147{
 148 return isX86DivHelperValid(inst);
 149}
 150
 151inline bool isX86Div32Valid(const Inst& inst)
 152{
 153 return isX86DivHelperValid(inst);
 154}
 155
 156inline bool isX86Div64Valid(const Inst& inst)
 157{
 158 return isX86DivHelperValid(inst);
 159}
 160
131161} } } // namespace JSC::B3::Air
132162
133163#endif // ENABLE(B3_JIT)
192259

Source/JavaScriptCore/b3/air/AirOpcode.opcodes

@@Neg32 UD:G
9696Neg64 UD:G
9797 Tmp
9898
 99Mul32 U:G, UD:G
 100 Tmp, Tmp
 101 Addr, Tmp
 102
 103X86ConvertToDoubleWord32 U:G, D:G
 104 Tmp*, Tmp*
 105
 106X86ConvertToDoubleWord64 U:G, D:G
 107 Tmp*, Tmp*
 108
 109X86Div32 UD:G, UD:G, U:G
 110 Tmp*, Tmp*, Tmp
 111
 112X86Div64 UD:G, UD:G, U:G
 113 Tmp*, Tmp*, Tmp
 114
99115Lea UA:G, D:G
100116 Addr, Tmp
101117

@@Xor64 U:G, UD:G
157173 Tmp, Addr
158174 Imm, Tmp
159175
160 Mul32 U:G, UD:G
161  Tmp, Tmp
162  Addr, Tmp
163 
164176# Note that Move operates over the full register size, which is either 32-bit or 64-bit depending on
165177# the platform. I'm not entirely sure that this is a good thing; it might be better to just have a
166178# Move64 instruction. OTOH, our MacroAssemblers already have this notion of "move()" that basically
192259

Source/JavaScriptCore/dfg/DFGBlockInsertionSet.h

@@public:
4545 void insert(size_t index, PassRefPtr<BasicBlock>);
4646 BasicBlock* insert(size_t index, float executionCount);
4747 BasicBlock* insertBefore(BasicBlock* before, float executionCount);
48 
 48
4949 bool execute();
5050
5151private:
192259

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

@@void SpeculativeJIT::compileArithDiv(Nod
33993399 }
34003400
34013401 m_jit.move(op1GPR, eax.gpr());
3402  m_jit.assembler().cdq();
3403  m_jit.assembler().idivl_r(op2GPR);
 3402 m_jit.x86ConvertToDoubleWord32();
 3403 m_jit.x86Div32(op2GPR);
34043404
34053405 if (op2TempGPR != InvalidGPRReg)
34063406 unlock(op2TempGPR);

@@void SpeculativeJIT::compileArithMod(Nod
35553555
35563556 m_jit.move(op1Gpr, eax.gpr());
35573557 m_jit.move(TrustedImm32(divisor), scratchGPR);
3558  m_jit.assembler().cdq();
3559  m_jit.assembler().idivl_r(scratchGPR);
 3558 m_jit.x86ConvertToDoubleWord32();
 3559 m_jit.x86Div32(scratchGPR);
35603560 if (shouldCheckNegativeZero(node->arithMode())) {
35613561 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
35623562 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));

@@void SpeculativeJIT::compileArithMod(Nod
36463646 }
36473647
36483648 m_jit.move(op1GPR, eax.gpr());
3649  m_jit.assembler().cdq();
3650  m_jit.assembler().idivl_r(op2GPR);
 3649 m_jit.x86ConvertToDoubleWord32();
 3650 m_jit.x86Div32(op2GPR);
36513651
36523652 if (op2TempGPR != InvalidGPRReg)
36533653 unlock(op2TempGPR);
192259

Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

@@void JIT::emit_op_mod(Instruction* curre
858858 Jump denominatorNotNeg1 = branch32(NotEqual, regT2, TrustedImm32(-1));
859859 addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
860860 denominatorNotNeg1.link(this);
861  m_assembler.cdq();
862  m_assembler.idivl_r(regT2);
 861 x86ConvertToDoubleWord32();
 862 x86Div32(regT2);
863863 Jump numeratorPositive = branch32(GreaterThanOrEqual, regT3, TrustedImm32(0));
864864 addSlowCase(branchTest32(Zero, regT1));
865865 numeratorPositive.link(this);
192259

Source/JavaScriptCore/jit/JITArithmetic.cpp

@@void JIT::emit_op_mod(Instruction* curre
623623 Jump denominatorNotNeg1 = branch32(NotEqual, ecx, TrustedImm32(-1));
624624 addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
625625 denominatorNotNeg1.link(this);
626  m_assembler.cdq();
627  m_assembler.idivl_r(ecx);
 626 x86ConvertToDoubleWord32();
 627 x86Div32(ecx);
628628 Jump numeratorPositive = branch32(GreaterThanOrEqual, regT4, TrustedImm32(0));
629629 addSlowCase(branchTest32(Zero, edx));
630630 numeratorPositive.link(this);
192259

Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

@@public:
763763 ASSERT(GPRInfo::regT0 == X86Registers::eax);
764764 move(GPRInfo::regT1, X86Registers::ecx);
765765 if (op == WASMOpExpressionI32::SDiv || op == WASMOpExpressionI32::SMod) {
766  m_assembler.cdq();
767  m_assembler.idivl_r(X86Registers::ecx);
 766 x86ConvertToDoubleWord32();
 767 x86Div32(X86Registers::ecx);
768768 } else {
769769 ASSERT(op == WASMOpExpressionI32::UDiv || op == WASMOpExpressionI32::UMod);
770770 xor32(X86Registers::edx, X86Registers::edx);
192259

Source/WTF/wtf/BubbleSort.h

@@void bubbleSort(IteratorType begin, Iter
8989{
9090 bubbleSort(
9191 begin, end,
92  [] (typename std::iterator_traits<IteratorType>::value_type left,
93  typename std::iterator_traits<IteratorType>::value_type right) -> bool {
 92 [] (const typename std::iterator_traits<IteratorType>::value_type& left,
 93 const typename std::iterator_traits<IteratorType>::value_type& right) -> bool {
9494 return left < right;
9595 });
9696}
192259

Source/WTF/wtf/Insertion.h

@@template<typename T>
3232class Insertion {
3333public:
3434 Insertion() { }
35 
36  Insertion(size_t index, T element)
 35
 36 template<typename U>
 37 Insertion(size_t index, U&& element)
3738 : m_index(index)
38  , m_element(element)
 39 , m_element(std::forward<U>(element))
3940 {
4041 }
4142
4243 size_t index() const { return m_index; }
43  T element() const { return m_element; }
 44 const T& element() const { return m_element; }
 45 T& element() { return m_element; }
4446
4547 bool operator<(const Insertion& other) const
4648 {

@@void executeInsertions(TargetVectorType&
6668 size_t firstIndex = insertions[indexInInsertions].index() + indexInInsertions;
6769 size_t indexOffset = indexInInsertions + 1;
6870 for (size_t i = lastIndex; --i > firstIndex;)
69  target[i] = target[i - indexOffset];
70  target[firstIndex] = insertions[indexInInsertions].element();
 71 target[i] = WTF::move(target[i - indexOffset]);
 72 target[firstIndex] = WTF::move(insertions[indexInInsertions].element());
7173 lastIndex = firstIndex;
7274 }
7375 insertions.resize(0);
192259