Compare commits

..

2 Commits

Author SHA1 Message Date
fur%netscape.com
1c43d4984f This is a copy of regalloc_code2_BRANCH from Netscape's private repository,
as it existed in January of 1998.


git-svn-id: svn://10.0.0.236/branches/regalloc_code2_BRANCH@22571 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 16:12:08 +00:00
(no author)
cfe021ff88 This commit was manufactured by cvs2svn to create branch
'regalloc_code2_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/regalloc_code2_BRANCH@22567 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 15:57:58 +00:00
359 changed files with 5188 additions and 32309 deletions

View File

@@ -0,0 +1,134 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "BitSet.h"
// Return the next bit after index set to true or -1 if none.
//
Int32 BitSet::nextOne(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(0)) {
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(0)) {
index = 0;
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
}
return -1;
}
// Return the next bit after index set to false or -1 if none.
//
Int32 BitSet::nextZero(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(~0)) {
for (; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(~0)) {
for (index = 0; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
}
return -1;
}
#ifdef DEBUG_LOG
// Print the set.
//
void BitSet::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
Int32 currentBit = i;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
Int32 nextBit = nextOne(currentBit);
if (nextBit != currentBit + 1) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
continue;
}
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
currentBit = nextBit;
nextBit = nextOne(nextBit);
}
if (currentBit > (i+1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
i = currentBit;
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,195 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _BITSET_H_
#define _BITSET_H_
#include "Fundamentals.h"
#include "LogModule.h"
#include "Pool.h"
#include <string.h>
//------------------------------------------------------------------------------
// BitSet -
class BitSet
{
private:
#if (PR_BITS_PER_WORD == 64)
typedef Uint64 Word;
#elif (PR_BITS_PER_WORD == 32)
typedef Uint32 Word;
#endif
static const nBitsInWord = PR_BITS_PER_WORD;
static const nBytesInWord = PR_BYTES_PER_WORD;
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
// Return the number of Word need to store the universe.
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
// Return the given element offset in its containing Word.
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
// Return the Word offset for the given element int the universe.
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
// Return the mask for the given bit index.
static Word getMask(Uint8 index) {return Word(1) << index;}
private:
Uint32 universeSize; // Size of the universe
Word* word; // universe memory.
private:
// No copy constructor.
BitSet(const BitSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
// Create a bitset of universeSize bits.
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
// Return the size of this bitset.
Uint32 getSize() const {return universeSize;}
// Clear the bitset.
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Clear the bit at index.
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
// Set the bitset.
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Set the bit at index.
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
// Return true if the bit at index is set.
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
// Union with the given bitset.
inline void or(const BitSet& set);
// Intersection with the given bitset.
inline void and(const BitSet& set);
// Difference with the given bitset.
inline void difference(const BitSet& set);
// Copy set.
inline BitSet& operator = (const BitSet& set);
// Return true if the bitset are identical.
friend bool operator == (const BitSet& set1, const BitSet& set2);
// Return true if the bitset are different.
friend bool operator != (const BitSet& set1, const BitSet& set2);
// Logical operators.
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
// Return the first bit at set to true or -1 if none.
Int32 firstOne() const {return nextOne(-1);}
// Return the next bit after index set to true or -1 if none.
Int32 nextOne(Int32 pos) const;
// Return the first bit at set to false or -1 if none.
Int32 firstZero() const {return nextZero(-1);}
// Return the next bit after index set to false or -1 if none.
Int32 nextZero(Int32 pos) const;
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return true if the walk is ordered.
static bool isOrdered() {return true;}
// Return the iterator for the first element of this set.
iterator begin() const {return firstOne();}
// Return the next iterator.
iterator advance(iterator pos) const {return nextOne(pos);}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == -1;}
// Return the element corresponding to the given iterator.
Uint32 get(iterator pos) const {return pos;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// Union with the given bitset.
//
inline void BitSet::or(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ |= *src++;
}
// Intersection with the given bitset.
//
inline void BitSet::and(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= *src++;
}
// Difference with the given bitset.
//
inline void BitSet::difference(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= ~*src++;
}
// Copy the given set into this set.
//
inline BitSet& BitSet::operator = (const BitSet& set)
{
checkUniverseCompatibility(set);
if (this != &set)
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
return *this;
}
// Return true if the given set is identical to this set.
inline bool operator == (const BitSet& set1, const BitSet& set2)
{
set1.checkUniverseCompatibility(set2);
if (&set1 == &set2)
return true;
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
}
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
#endif // _BITSET_H

View File

@@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _COALESCING_H_
#define _COALESCING_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "RegisterPressure.h"
#include "InterferenceGraph.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#if 1
// Performing an ultra conservative coalescing meens that when we look at
// candidates (source,destination) for coalescing we need to make sure
// that the combined interference of the source and destination register
// will not exceed the total number of register available for the register
// class.
#define ULTRA_CONSERVATIVE_COALESCING
#else
// If we are not doing an ultra conservative coalescing we have to make sure
// that the total number of neighbor whose degree is greater than the total
// number of register is not greater than the total number of register.
#undef ULTRA_CONSERVATIVE_COALESCING
#endif
template <class RegisterPressure>
struct Coalescing
{
static bool coalesce(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
// Initialize the lookup table
//
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* newRange = new RegisterName[2 * rangeCount];
RegisterName* coalescedRange = &newRange[rangeCount];
RegisterName* name2range = registerAllocator.name2range;
init(coalescedRange, rangeCount);
SparseSet interferences(pool, rangeCount);
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool removedInstructions = false;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.lndList;
Uint32 nNodes = controlGraph.nNodes;
// Walk the nodes in the loop nesting depth list.
for (Int32 n = nNodes - 1; n >= 0; n--) {
InstructionList& instructions = nodes[n]->getInstructions();
InstructionList::iterator it = instructions.begin();
while (!instructions.done(it)) {
Instruction& instruction = instructions.get(it);
it = instructions.advance(it);
if ((instruction.getFlags() & ifCopy) != 0) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
if (source == destination) {
instruction.remove();
} else if (!iGraph.interfere(source, destination)) {
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
#ifdef ULTRA_CONSERVATIVE_COALESCING
interferences.clear();
InterferenceVector* vector;
for (vector = sourceVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
for (vector = destinationVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
Uint32 count = interferences.getSize();
#else // ULTRA_CONSERVATIVE_COALESCING
trespass("not implemented");
Uint32 count = 0;
#endif // ULTRA_CONSERVATIVE_COALESCING
if (count < 6 /* FIX: should get the number from the class */) {
// Update the interferences vector.
if (sourceVector == NULL) {
iGraph.setInterferenceVector(source, destinationVector);
sourceVector = destinationVector;
} else if (destinationVector == NULL)
iGraph.setInterferenceVector(destination, sourceVector);
else {
InterferenceVector* last = NULL;
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
last = v;
assert(last);
last->next = destinationVector;
iGraph.setInterferenceVector(destination, sourceVector);
}
// Update the interference matrix.
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
RegisterName* neighbors = v->neighbors;
for (Uint32 i = 0; i < v->count; i++) {
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
iGraph.setInterference(neighbor, source);
iGraph.setInterference(neighbor, destination);
}
}
instruction.remove();
coalescedRange[source] = destination;
removedInstructions = true;
}
}
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
delete newRange;
return removedInstructions;
}
#endif // _COALESCING_H_

View File

@@ -0,0 +1,283 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NEW_LAURENTM_CODE
#include "Coloring.h"
#include "VirtualRegister.h"
#include "FastBitSet.h"
#include "FastBitMatrix.h"
#include "CpuInfo.h"
bool Coloring::
assignRegisters(FastBitMatrix& interferenceMatrix)
{
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
}
PRInt32 Coloring::
getLowestSpillCostRegister(FastBitSet& bitset)
{
PRInt32 lowest = bitset.firstOne();
if (lowest != -1)
{
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
{
cost = vReg.spillInfo.spillCost;
lowest = r;
}
}
}
return lowest;
}
PRUint32* Coloring::
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
{
// first we construct the sets low and high. low contains all nodes of degree
// inferior to the number of register available on the processor. All the
// nodes with an high degree and a finite spill cost are placed in high.
// Nodes of high degree and infinite spill cost are not included in either sets.
PRUint32 nRegisters = vRegManager.count();
FastBitSet low(pool, nRegisters);
FastBitSet high(pool, nRegisters);
FastBitSet stack(pool, nRegisters);
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
if (vReg.getClass() == vrcStackSlot)
{
stack.set(i);
vReg.colorRegister(nRegisters);
}
else
{
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
low.set(i);
else // if (!vReg.spillInfo.infiniteSpillCost)
high.set(i);
// Set coloring info.
vReg.spillInfo.willSpill = false;
switch(vReg.getClass())
{
case vrcInteger:
vReg.colorRegister(LAST_GREGISTER + 1);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
vReg.colorRegister(LAST_FPREGISTER + 1);
break;
default:
PR_ASSERT(false); // Cannot happen.
}
}
}
// push the stack registers
PRInt32 j;
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
*stackPtr++ = j;
// simplify
while (true)
{
PRInt32 r;
while ((r = getLowestSpillCostRegister(low)) != -1)
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
/* update low and high */
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
{
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
// if the new interference degree of one of his neighbor becomes
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
PRUint32 maxInterference = 0;
switch (neighbor.getClass())
{
case vrcInteger:
maxInterference = NUMBER_OF_GREGISTERS;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
maxInterference = NUMBER_OF_FPREGISTERS;
break;
default:
PR_ASSERT(false);
}
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
{
high.clear(j);
low.set(j);
}
vReg.colorInfo.interferenceDegree--;
interferenceMatrix.clear(r, j);
interferenceMatrix.clear(j, r);
}
low.clear(r);
// Push this register.
*stackPtr++ = r;
}
if ((r = getLowestSpillCostRegister(high)) != -1)
{
high.clear(r);
low.set(r);
}
else
break;
}
return stackPtr;
}
bool Coloring::
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
{
PRUint32 nRegisters = vRegManager.count();
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
FastBitSet usedStack(nRegisters + 1);
bool success = true;
Int32 lastUsedSSR = -1;
// select
while (stackPtr != stackBase)
{
// Pop one register.
PRUint32 r = *--stackPtr;
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
if (vReg.getClass() == vrcStackSlot)
// Stack slots coloring.
{
usedStack.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
Int32 color = usedStack.firstZero();
vReg.colorRegister(color);
if (color > lastUsedSSR)
lastUsedSSR = color;
}
else
// Integer & Floating point register coloring.
{
usedRegisters.clear();
preColoredRegisters.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
{
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
usedRegisters.set(nvReg.getColor());
if (nvReg.isPreColored())
preColoredRegisters.set(nvReg.getPreColor());
}
if (vReg.hasSpecialInterference)
usedRegisters |= vReg.specialInterference;
PRInt8 c = -1;
PRInt8 maxColor = 0;
PRInt8 firstColor = 0;
switch (vReg.getClass())
{
case vrcInteger:
firstColor = FIRST_GREGISTER;
maxColor = LAST_GREGISTER;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
firstColor = FIRST_FPREGISTER;
maxColor = LAST_FPREGISTER;
break;
default:
PR_ASSERT(false);
}
if (vReg.isPreColored())
{
c = vReg.getPreColor();
if (usedRegisters.test(c))
c = -1;
}
else
{
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
c = usedRegisters.nextZero(c)) {}
}
if ((c >= 0) && (c <= maxColor))
{
vReg.colorRegister(c);
}
else
{
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
vReg.spillInfo.willSpill = true;
success = false;
}
}
}
#ifdef DEBUG
if (success)
{
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
switch (vReg.getClass())
{
case vrcInteger:
if (vReg.getColor() > LAST_GREGISTER)
PR_ASSERT(false);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
#if NUMBER_OF_FPREGISTERS != 0
if (vReg.getColor() > LAST_FPREGISTER)
PR_ASSERT(false);
#endif
break;
default:
break;
}
}
}
#endif
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
return success;
}
#endif // NEW_LAURENTM_CODE

View File

@@ -0,0 +1,284 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "VirtualRegister.h"
#include "InterferenceGraph.h"
#include "SparseSet.h"
#include "Spilling.h"
#include "Splits.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
class Coloring
{
private:
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
public:
static bool color(RegisterAllocator& registerAllocator);
static void finalColoring(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
{
RegisterName* color = registerAllocator.color;
RegisterName* name2range = registerAllocator.name2range;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = usePtr->getRegisterID();
setColoredRegister(rid);
usePtr->setRegisterID(rid);
#endif // DEBUG
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = definePtr->getRegisterID();
setColoredRegister(rid);
definePtr->setRegisterID(rid);
#endif // DEBUG
}
}
}
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* color = new RegisterName[rangeCount];
registerAllocator.color = color;
for (Uint32 r = 1; r < rangeCount; r++)
color[r] = RegisterName(6); // FIX;
// Color the preColored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID) {
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
}
SpillCost* cost = registerAllocator.spillCost;
Pool& pool = registerAllocator.pool;
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
registerAllocator.willSpill = &spill;
SparseSet neighborColors(pool, 6); // FIX
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool coloringFailed = false;
while (coloringStackPtr > coloringStack) {
RegisterName range = *--coloringStackPtr;
if (!cost[range].infinite && cost[range].cost < 0) {
coloringFailed = true;
spill.set(range);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
} else {
neighborColors.clear();
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >= 0; --i) {
RegisterName neighborColor = color[vector->neighbors[i]];
if (neighborColor < 6) // FIX
neighborColors.set(neighborColor);
}
if (neighborColors.getSize() == 6) { // FIX
coloringFailed = true;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
spill.set(range);
} else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
} else {
for (Uint32 i = 0; i < 6; i++) // FIX
if (!neighborColors.test(i)) {
fprintf(stdout, "\twill color %d as %d\n", range, i);
color[range] = RegisterName(i);
break;
}
}
}
}
#ifdef DEBUG_LOG
if (coloringFailed) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
spill.printPretty(UT_LOG_MODULE(RegAlloc));
} else {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
for (Uint32 i = 1; i < rangeCount; i++)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
}
#endif
return !coloringFailed;
}
template <class RegisterPressure>
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
{
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
SpillCost* spillCost = registerAllocator.spillCost;
Uint32 rangeCount = registerAllocator.rangeCount;
Uint32* degree = new Uint32[rangeCount];
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
InterferenceVector* vector = iGraph.getInterferenceVector(i);
degree[i] = (vector != NULL) ? vector->count : 0;
}
Pool& pool = registerAllocator.pool;
SparseSet low(pool, rangeCount);
SparseSet high(pool, rangeCount);
SparseSet highInfinite(pool, rangeCount);
SparseSet preColored(pool, rangeCount);
// Get the precolored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID)
preColored.set(name2range[getName(machinePtr->id)]);
// Insert the live ranges in the sets.
//
for (Uint32 range = 1; range < rangeCount; range++)
if (!preColored.test(range))
if (degree[range] < 6) // FIX
low.set(range);
else if (!spillCost[range].infinite)
high.set(range);
else
highInfinite.set(range);
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
low.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
high.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
#endif // DEBUG_LOG
RegisterName* coloringStackPtr = coloringStack;
while (low.getSize() != 0 || high.getSize() != 0) {
while (low.getSize() != 0) {
RegisterName range = RegisterName(low.getOne());
low.clear(range);
*coloringStackPtr++ = range;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = (vector->count - 1); i >= 0; --i) {
RegisterName neighbor = vector->neighbors[i];
degree[neighbor]--;
if (degree[neighbor] < 6) // FIX
if (high.test(neighbor)) {
high.clear(neighbor);
low.set(neighbor);
} else if (highInfinite.test(neighbor)) {
highInfinite.clear(neighbor);
low.set(neighbor);
}
}
}
if (high.getSize() != 0) {
RegisterName best = RegisterName(high.getOne());
double bestCost = spillCost[best].cost;
double bestDegree = degree[best];
// Choose the next best candidate.
//
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
RegisterName range = RegisterName(high.get(i));
double thisCost = spillCost[range].cost;
double thisDegree = degree[range];
if (thisCost * bestDegree < bestCost * thisDegree) {
best = range;
bestCost = thisCost;
bestDegree = thisDegree;
}
}
high.clear(best);
low.set(best);
}
}
assert(highInfinite.getSize() == 0);
delete degree;
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
#endif // DEBUG_LOG
return coloringStackPtr;
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
{
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
}

View File

@@ -0,0 +1,212 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include <string.h>
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "DominatorGraph.h"
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
{
Uint32 nNodes = controlGraph.nNodes;
GtoV = new Uint32[nNodes + 1];
VtoG = new Uint32[nNodes + 1];
Uint32 v = 1;
for (Uint32 n = 0; n < nNodes; n++) {
VtoG[v] = n;
GtoV[n] = v++;
}
// Initialize all the 1-based arrays.
//
parent = new Uint32[v];
semi = new Uint32[v];
vertex = new Uint32[v];
label = new Uint32[v];
size = new Uint32[v];
ancestor = new Uint32[v];
child = new Uint32[v];
dom = new Uint32[v];
bucket = new DGLinkedList*[v];
memset(semi, '\0', v * sizeof(Uint32));
memset(bucket, '\0', v * sizeof(DGLinkedList*));
vCount = v;
build();
delete parent;
delete semi;
delete vertex;
delete label;
delete size;
delete ancestor;
delete child;
delete dom;
delete bucket;
}
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
{
semi[vx] = ++n;
vertex[n] = label[vx] = vx;
ancestor[vx] = child[vx] = 0;
size[vx] = 1;
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
ControlEdge* successorEnd = node.getSuccessorsEnd();
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
if (semi[w] == 0) {
parent[w] = vx;
n = DFS(w, n);
}
}
return n;
}
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
{
Uint32 s = w;
while (semi[label[w]] < semi[label[child[s]]]) {
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
ancestor[child[s]] = s;
child[s] = child[child[s]];
} else {
size[child[s]] = size[s];
s = ancestor[s] = child[s];
}
}
label[s] = label[w];
size[vx] += size[w];
if(size[vx] < (size[w] << 1)) {
Uint32 t = s;
s = child[vx];
child[vx] = t;
}
while( s != 0 ) {
ancestor[s] = vx;
s = child[s];
}
}
void DominatorGraph::COMPRESS(Uint32 vx)
{
if(ancestor[ancestor[vx]] != 0) {
COMPRESS(ancestor[vx]);
if(semi[label[ancestor[vx]]] < semi[label[vx]])
label[vx] = label[ancestor[vx]];
ancestor[vx] = ancestor[ancestor[vx]];
}
}
Uint32 DominatorGraph::EVAL(Uint32 vx)
{
if(ancestor[vx] == 0)
return label[vx];
COMPRESS(vx);
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
}
void DominatorGraph::build()
{
Uint32 n = DFS(GtoV[0], 0);
size[0] = label[0] = semi[0];
for (Uint32 i = n; i >= 2; i--) {
Uint32 w = vertex[i];
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
Uint32 u = EVAL(vx);
if(semi[u] < semi[w])
semi[w] = semi[u];
}
DGLinkedList* elem = new DGLinkedList();
elem->next = bucket[vertex[semi[w]]];
elem->index = w;
bucket[vertex[semi[w]]] = elem;
LINK(parent[w], w);
elem = bucket[parent[w]];
while(elem != NULL) {
Uint32 vx = elem->index;
Uint32 u = EVAL(vx);
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
elem = elem->next;
}
}
memset(size, '\0', n * sizeof(Uint32));
Pool& pool = controlGraph.pool;
nodes = new(pool) DGNode[n];
for(Uint32 j = 2; j <= n; j++) {
Uint32 w = vertex[j];
Uint32 d = dom[w];
if(d != vertex[semi[w]]) {
d = dom[d];
dom[w] = d;
}
size[d]++;
}
dom[GtoV[0]] = 0;
for (Uint32 k = 1; k <= n; k++) {
DGNode& node = nodes[VtoG[k]];
Uint32 count = size[k];
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
}
for (Uint32 l = 2; l <= n; l++)
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
}
#ifdef DEBUG_LOG
void DominatorGraph::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 i = 0; i < nNodes; i++) {
DGNode& node = nodes[i];
if (node.successorsBegin != node.successorsEnd) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _DOMINATOR_GRAPH_H_
#define _DOMINATOR_GRAPH_H_
#include "LogModule.h"
class ControlGraph;
struct DGNode
{
Uint32* successorsBegin;
Uint32* successorsEnd;
};
struct DGLinkedList
{
DGLinkedList* next;
Uint32 index;
};
class DominatorGraph
{
private:
ControlGraph& controlGraph;
Uint32 vCount;
Uint32* VtoG;
Uint32* GtoV;
Uint32* parent;
Uint32* semi;
Uint32* vertex;
Uint32* label;
Uint32* size;
Uint32* ancestor;
Uint32* child;
Uint32* dom;
DGLinkedList** bucket;
DGNode* nodes;
private:
void build();
Uint32 DFS(Uint32 vx, Uint32 n);
void LINK(Uint32 vx, Uint32 w);
void COMPRESS(Uint32 vx);
Uint32 EVAL(Uint32 vx);
public:
DominatorGraph(ControlGraph& controlGraph);
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
#endif // _DOMINATOR_GRAPH_H_

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -16,6 +16,5 @@
* Reserved.
*/
#include "MacPrefix.h"
#include "Fundamentals.h"
#include "HashSet.h"

View File

@@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _HASH_SET_H_
#define _HASH_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include <string.h>
struct HashSetElement
{
Uint32 index;
HashSetElement* next;
};
class HashSet
{
private:
static const hashSize = 64;
// Return the hash code for the given element index.
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
private:
Pool& allocationPool;
HashSetElement** bucket;
HashSetElement* free;
private:
// No copy constructor.
HashSet(const HashSet&);
// No copy operator.
void operator = (const HashSet&);
public:
// Create a new HashSet.
inline HashSet(Pool& pool, Uint32 universeSize);
// Clear the hashset.
void clear();
// Clear the element for the given index.
void clear(Uint32 index);
// Set the element for the given index.
void set(Uint32 index);
// Return true if the element at index is a member.
bool test(Uint32 index) const;
// Union with the given hashset.
inline void or(const HashSet& set);
// Intersection with the given hashset.
inline void and(const HashSet& set);
// Difference with the given hashset.
inline void difference(const HashSet& set);
// Logical operators.
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef HashSetElement* iterator;
// Return the iterator for the first element of this set.
iterator begin() const;
// Return the next iterator.
iterator advance(iterator pos) const;
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == NULL;}
};
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
: allocationPool(pool), free(NULL)
{
bucket = new(pool) HashSetElement*[hashSize];
memset(bucket, '\0', sizeof(HashSetElement*));
}
#endif // _HASH_SET_H_

View File

@@ -0,0 +1,213 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _INDEXED_POOL_H_
#define _INDEXED_POOL_H_
#include "Fundamentals.h"
#include <string.h>
#include <stdlib.h>
//------------------------------------------------------------------------------
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
// IndexedObject.
//
// When the indexed pool is ask to allocate and initialize a new object (using
// the operator new(anIndexedPool) it will zero the memory used to store the
// object and initialize the field 'index' of this object to its position in
// the pool.
//
// An object allocated by the indexed pool can be freed by calling the method
// IndexedPool::release(IndexedElement& objectIndex).
//
// example:
//
// IndexedPool<IndexedElement> elementPool;
//
// IndexedElement& element1 = *new(elementPool) IndexedElement();
// IndexedElement& element2 = *new(elementPool) IndexedElement();
//
// indexedPool.release(element1);
// IndexedElement& element3 = *new(elementPool) IndexedElement();
//
// At this point element1 is no longer a valid object, element2 is at
// index 2 and element3 is at index 1.
//
//------------------------------------------------------------------------------
// IndexedObject -
//
template<class Object>
struct IndexedObject
{
Uint32 index; // Index in the pool.
Object* next; // Used to link IndexedObject together.
Uint32 getIndex() {return index;}
};
//------------------------------------------------------------------------------
// IndexedPool<IndexedObject> -
//
template <class IndexedObject>
class IndexedPool
{
private:
static const blockSize = 4; // Size of one block.
Uint32 nBlocks; // Number of blocks in the pool.
IndexedObject** block; // Array of block pointers.
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
Uint32 nextIndex; // Index of the next free object in the last block.
private:
void allocateAnotherBlock();
IndexedObject& newObject();
public:
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
~IndexedPool();
IndexedObject& get(Uint32 index) const;
void release(IndexedObject& object);
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
// Return the universe size.
Uint32 getSize() {return nextIndex;}
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
};
// Free all the memory allocated for this object.
//
template <class IndexedObject>
IndexedPool<IndexedObject>::~IndexedPool()
{
for (Uint32 n = 0; n < nBlocks; n++)
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
}
// Release the given. This object will be iserted in the chained
// list of free IndexedObjects. To minimize the fragmentation the chained list
// is ordered by ascending indexes.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::release(IndexedObject& object)
{
Uint32 index = object.index;
IndexedObject* list = freeObjects;
assert(&object == &get(index)); // Make sure that object is owned by this pool.
if (list == NULL) { // The list is empty.
freeObjects = &object;
object.next = NULL;
} else { // The list contains at least 1 element.
if (index < list->index) { // insert as first element.
freeObjects = &object;
object.next = list;
} else { // Find this object's place.
while ((list->next) != NULL && (list->next->index < index))
list = list->next;
object.next = list->next;
list->next = &object;
}
}
#ifdef DEBUG
// Sanity check to be sure that the list is correctly ordered.
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
if (obj->next != NULL)
assert(obj->index < obj->next->index);
#endif
}
// Create a new block of IndexedObjects. We will allocate the memory to
// store IndexedPool::blockSize IndexedObject and the new Array of block
// pointers.
// The newly created IndexedObjects will not be initialized.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::allocateAnotherBlock()
{
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
memcpy(memory, block, nBlocks * sizeof(Uint32));
block = (IndexedObject **) memory;
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
block[nBlocks] = &objects[-(nBlocks * blockSize)];
nBlocks++;
}
// Return the IndexedObject at the position 'index' in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
{
Uint32 blockIndex = index / blockSize;
assert(blockIndex < nBlocks);
return block[blockIndex][index];
}
// Return the reference of an unused object in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::newObject()
{
if (freeObjects != NULL) {
IndexedObject& newObject = *freeObjects;
freeObjects = newObject.next;
return newObject;
}
Uint32 nextIndex = this->nextIndex++;
Uint32 blockIndex = nextIndex / blockSize;
while (blockIndex >= nBlocks)
allocateAnotherBlock();
IndexedObject& newObject = block[blockIndex][nextIndex];
newObject.index = nextIndex;
return newObject;
}
// Return the address of the next unsused object in the given
// indexed pool. The field index of the newly allocated object
// will be initialized to the corresponding index of this object
// in the pool.
//
template <class IndexedObject>
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
{
assert(size == sizeof(IndexedObject));
return (void *) &pool.newObject();
}
#endif // _INDEXED_POOL_H_

View File

@@ -0,0 +1,258 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _INTERFERENCE_GRAPH_H_
#define _INTERFERENCE_GRAPH_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "Primitives.h"
#include "Instruction.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "SparseSet.h"
#include <string.h>
struct InterferenceVector
{
Uint32 count;
InterferenceVector* next;
RegisterName* neighbors;
InterferenceVector() : count(0), next(NULL) {}
};
class RegisterAllocator;
template <class RegisterPressure>
class InterferenceGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* interferences;
InterferenceVector** vector;
Uint32* offset;
Uint32 rangeCount;
private:
// No copy constructor.
InterferenceGraph(const InterferenceGraph&);
// No copy operator.
void operator = (const InterferenceGraph&);
// Check if reg is a member of the universe.
void checkMember(RegisterName name) {assert(name < rangeCount);}
// Return the edge index for the interference between name1 and name2.
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
public:
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
// Calculate the interferences.
void build();
// Return true if reg1 and reg2 interfere.
bool interfere(RegisterName name1, RegisterName name2);
// Return the interference vector for the given register or NULL if there is none.
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
// Set the interference between name1 and name2.
void setInterference(RegisterName name1, RegisterName name2);
// Set the interference vector for the given register.
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
#ifdef DEBUG_LOG
// Print the interferences.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
// Initialize the structures.
//
offset = new(pool) Uint32[rangeCount + 1];
vector = new(pool) InterferenceVector*[rangeCount];
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
Uint32 o = 0;
offset[0] = 0;
for (Uint32 i = 1; i <= rangeCount; ++i) {
offset[i] = o;
o += i;
}
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
registerAllocator.liveness = liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
// Create the interferences.
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
RegisterName live = RegisterName(currentLive.get(e));
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
if (vector[define] == NULL)
vector[define] = new(pool) InterferenceVector();
vector[define]->count++;
if (vector[live] == NULL)
vector[live] = new(pool) InterferenceVector();
vector[live]->count++;
setInterference(live, define);
}
}
}
// Now update the liveness.
//
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
}
}
// Allocate the memory to store the interferences.
//
for (Uint32 e = 0; e < rangeCount; e++)
if (vector[e] != NULL) {
InterferenceVector& v = *vector[e];
v.neighbors = new(pool) RegisterName[v.count];
v.count = 0;
}
// Initialize the edges.
//
if (RegisterPressure::Set::isOrdered()) {
RegisterName name1 = RegisterName(0);
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
Uint32 interferenceIndex = interferences->get(i);
while(interferenceIndex >= offset[name1 + 1])
name1 = RegisterName(name1 + 1);
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
assert(interfere(name1, name2));
InterferenceVector& vector1 = *vector[name1];
vector1.neighbors[vector1.count++] = name2;
InterferenceVector& vector2 = *vector[name2];
vector2.neighbors[vector2.count++] = name1;
}
} else {
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
}
}
template <class RegisterPressure>
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
{
checkMember(name1); checkMember(name2);
assert(name1 != name2); // This is not possible.
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
}
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
{
interferences->set(getEdgeIndex(name1, name2));
}
template <class RegisterPressure>
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
{
return interferences->test(getEdgeIndex(name1, name2));
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
if (vector[i] != NULL) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
for (Uint32 j = 0; j < v->count; j++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
if (v->next != NULL || j != (v->count - 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
}
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _INTERFERENCE_GRAPH_H_

View File

@@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVE_RANGE_H_
#define _LIVE_RANGE_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
template <class RegisterPressure>
struct LiveRange
{
static void build(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
{
// Intialize the lookup table.
//
Uint32 nameCount = registerAllocator.nameCount;
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
RegisterName* rangeName = &nameTable[nameCount];
init(rangeName, nameCount);
// Walk the graph.
//
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
SparseSet destination(registerAllocator.pool, nameCount);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
destination.clear();
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
Instruction& phiNode = phiNodes.get(i);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
}
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
RegisterName destinationRoot = findRoot(destinationName, rangeName);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName sourceName = usePtr->getRegisterName();
RegisterName sourceRoot = findRoot(sourceName, rangeName);
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
rangeName[sourceRoot] = destinationRoot;
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
}
#endif // _LIVE_RANGE_H_

View File

@@ -0,0 +1,163 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVE_RANGE_GRAPH_
#define _LIVE_RANGE_GRAPH_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
class RegisterAllocator;
template <class RegisterPressure>
class LiveRangeGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* edges;
Uint32 rangeCount;
public:
//
//
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
//
//
void build();
//
//
void addEdge(RegisterName name1, RegisterName name2);
//
//
bool haveEdge(RegisterName name1, RegisterName name2);
#ifdef DEBUG_LOG
//
//
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (define != live && registerAllocator.canInterfere(define, live))
addEdge(define, live);
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName use = name2range[usePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (use != live && registerAllocator.canInterfere(use, live))
addEdge(use, live);
}
}
}
}
}
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
edges->set(name1 * rangeCount + name2);
}
template <class RegisterPressure>
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
return edges->test(name1 * rangeCount + name2);
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVE_RANGE_GRAPH_

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -16,6 +16,6 @@
* Reserved.
*/
#include "Fundamentals.h"
#include "Liveness.h"
#include "MacPrefix_debug.h"

View File

@@ -0,0 +1,301 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVENESS_H_
#define _LIVENESS_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
// ----------------------------------------------------------------------------
// LivenessInfo -
template <class RegisterPressure>
struct LivenessInfo
{
RegisterPressure::Set* liveIn;
RegisterPressure::Set* liveOut;
DEBUG_LOG_ONLY(Uint32 size);
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// ----------------------------------------------------------------------------
// Liveness
//
// The liveness is defined by the following data-flow equations:
//
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
// LiveOut(n) = U LiveIn(s) (s a successor of n).
//
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
// is the set of defined registers in the block n, LiveIn(n) is the set of
// live registers at the begining of the block n and LiveOut(n) is the set
// of live registers at the end of the block n.
//
//
// We will compute the liveness analysis in two stages:
//
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
// for each block n.
// 2- Perform a backward data-flow analysis to propagate the liveness information
// through the entire control-flow graph.
//
template <class RegisterPressure>
struct Liveness
{
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
};
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = name2range[usePtr->getRegisterName()];
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(name2range[definePtr->getRegisterName()]);
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, rangeCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* usedByPhiNodes = NULL;
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
InstructionList& phiNodes = node.getPhiNodeInstructions();
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
currentKilled.set(define.getRegisterName());
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
const ControlEdgeList& predecessors = node.getPredecessors();
ControlEdgeList::iterator p = predecessors.begin();
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
if (usePtr->isRegister())
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
}
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = usePtr->getRegisterName();
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(definePtr->getRegisterName());
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, nameCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// Insert the phiNodes contribution.
if (usedByPhiNodes != NULL)
temp |= usedByPhiNodes[n];
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
{
for (Uint32 n = 0; n < size; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
liveIn[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
liveOut[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVENESS_H_

View File

@@ -0,0 +1,40 @@
#! gmake
DEPTH = ../..
MODULE_NAME = RegisterAllocator
include $(DEPTH)/config/config.mk
INCLUDES += \
-I$(DEPTH)/Utilities/General \
-I$(DEPTH)/Utilities/zlib \
-I$(DEPTH)/Runtime/ClassReader \
-I$(DEPTH)/Runtime/NativeMethods \
-I$(DEPTH)/Runtime/System \
-I$(DEPTH)/Runtime/ClassInfo \
-I$(DEPTH)/Runtime/FileReader \
-I$(DEPTH)/Compiler/PrimitiveGraph \
-I$(DEPTH)/Compiler/FrontEnd \
-I$(DEPTH)/Compiler/Optimizer \
-I$(DEPTH)/Compiler/CodeGenerator \
-I$(DEPTH)/Compiler/CodeGenerator/md \
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
-I$(DEPTH)/Compiler/RegisterAllocator \
-I$(DEPTH)/Driver/StandAloneJava \
-I$(DEPTH)/Debugger \
$(NULL)
CXXSRCS = \
RegisterAllocator.cpp \
RegisterAllocatorTools.cpp \
DominatorGraph.cpp \
VirtualRegister.cpp \
BitSet.cpp \
SparseSet.cpp \
$(NULL)
include $(DEPTH)/config/rules.mk
libs:: $(MODULE)

View File

@@ -0,0 +1,392 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _PHI_NODE_REMOVER_H_
#define _PHI_NODE_REMOVER_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "DominatorGraph.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "Liveness.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "SparseSet.h"
#include <string.h>
//------------------------------------------------------------------------------
// RegisterNameNode -
struct RegisterNameNode
{
RegisterNameNode* next;
RegisterName newName;
Uint32 nextPushed;
};
//------------------------------------------------------------------------------
// CopyData -
struct CopyData
{
RegisterName source;
RegisterClassKind classKind;
Uint32 useCount;
bool isLiveOut;
RegisterName sourceNameToUse;
RegisterName temporaryName;
RegisterNameNode* newName;
};
//------------------------------------------------------------------------------
// PhiNodeRemover<RegisterPressure> -
template <class RegisterPressure>
struct PhiNodeRemover
{
// Replace the phi nodes by copy instructions.
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
// Split some of the critical edges and return true if there are still some
// in the graph after that.
//
static bool splitCriticalEdges(ControlGraph& /*cg*/)
{
// FIX: not implemented.
return true;
}
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
{
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
if (pushed.test(oldName))
(*stack)->newName = newName;
else {
newNode.newName = newName;
newNode.nextPushed = *nodeListPointer;
*nodeListPointer = oldName;
newNode.next = *stack;
*stack = &newNode;
pushed.set(oldName);
}
}
template <class RegisterPressure>
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Initialize the local variables.
//
// When we insert the copies we will also need to create new VirtualRegisters for
// the insertion of temporaries. The maximum number of temporary register will not
// exceed the number of phiNodes in the primitive graph.
Uint32 nameCount = vrManager.getSize();
Uint32 maxNameCount = nameCount;
for (Uint32 n = 0; n < nNodes; n++)
maxNameCount += nodes[n]->getPhiNodes().length();
// If the CFG contains some critical edges (backward edge which source has more than one
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
// information to be able to insert temporary copies.
RegisterPressure::Set* liveOut = NULL;
if (splitCriticalEdges(controlGraph))
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
DominatorGraph dGraph(controlGraph);
SparseSet pushed(pool, maxNameCount);
SparseSet destinationList(pool, maxNameCount);
SparseSet workList(pool, maxNameCount);
CopyData* copyStats = new(pool) CopyData[maxNameCount];
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
struct NodeStack {
Uint32* next;
Uint32* limit;
Uint32 pushedList;
};
// Allocate the node stack and initialize the node stack pointer.
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
NodeStack* nodeStackPtr = nodeStack;
// We start by the begin node.
Uint32 startNode = 0;
Uint32* next = &startNode;
Uint32* limit = &startNode + 1;
while (true) {
if (next == limit) {
// If there are no more node in the sibling, we have to pop the current
// frame from the stack and update the copyStats of the pushed nodes.
//
if (nodeStackPtr == nodeStack)
// We are at the bottom of the stack and there are no more nodes
// to look at. We are done !
break;
--nodeStackPtr;
// We are done with all the children of this node in the dominator tree.
// We need to update the copy information of all the new names pushed
// during the walk over this node.
Uint32 pushedList = nodeStackPtr->pushedList;
while (pushedList != 0) {
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
pushedList = nextName;
}
// restore the previous frame.
next = nodeStackPtr->next;
limit = nodeStackPtr->limit;
} else {
Uint32 currentNode = *next++;
Uint32 pushedList = 0;
// Initialize the sets.
pushed.clear();
destinationList.clear();
// STEP1:
// Walk the instruction list and to replace all the instruction uses with their new name.
// If the instruction is a phi node and its defined register is alive at the end of this
// block then we push the defined register into the stack.
//
ControlNode& node = *nodes[currentNode];
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
InstructionList& phiNodes = node.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
if (currentLiveOut != NULL) {
// This is a phi node and we have to push its defined name if it is live
// at the end of the node. We only need to do this if the CFG has critical edges.
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
if (currentLiveOut->test(name))
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
}
// STEP2:
// Look at this node's successors' phiNodes. We keep track of the number of time
// a VR will be used by another copy instruction and insert each definition into the
// destinationList. This is the only pass over this node's successors as we will
// get all the information we need in the CopyData structures.
//
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
Uint32 useIndex = successorEdgePtr->getIndex();
ControlNode& successor = successorEdgePtr->getTarget();
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
// as soon as we find an instruction which is not a phi node
InstructionList& phiNodes = successor.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
assert(source.isRegister() && destination.isRegister());
RegisterName sourceName = source.getRegisterName();
RegisterName destinationName = destination.getRegisterName();
// Get the correct name for the source.
if (copyStats[sourceName].newName != NULL)
sourceName = copyStats[sourceName].newName->newName;
// Update the CopyData structures.
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
copyStats[destinationName].source = sourceName;
copyStats[destinationName].classKind = destination.getRegisterClass();
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
copyStats[destinationName].sourceNameToUse = destinationName;
copyStats[sourceName].sourceNameToUse = sourceName;
copyStats[sourceName].useCount++;
destinationList.set(destinationName);
}
}
}
// STEP3:
// Insert into the worklist only the destination registers that will be not used in
// another copy instruction in this block.
//
assert(workList.getSize() == 0);
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
Uint32 dest = destinationList.get(d);
if (copyStats[dest].useCount == 0)
workList.set(dest);
}
// STEP4:
// Insert the copy instructions.
//
Uint32 destinationListSize = destinationList.getSize();
InstructionList::iterator endOfTheNode = instructions.end();
// Find the right place to insert the copy instructions.
if (destinationListSize != 0)
while (instructions.get(endOfTheNode).getFlags() & ifControl)
endOfTheNode = instructions.retreat(endOfTheNode);
while (destinationListSize != 0) {
while(workList.getSize()) {
RegisterName destinationName = RegisterName(workList.getOne());
RegisterName sourceName = copyStats[destinationName].source;
workList.clear(destinationName);
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
// Lost copy problem.
copyStats[destinationName].isLiveOut = false;
RegisterName sourceName = destinationName;
RegisterClassKind classKind = copyStats[sourceName].classKind;
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].useCount = 0;
// We need to insert a copy to a temporary register to keep the
// source register valid at the end of the node defining it.
// This copy will be inserted right after the phi node defining it.
RegisterName from = copyStats[sourceName].sourceNameToUse;
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
copyStats[sourceName].temporaryName = destinationName;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
}
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterClassKind classKind = copyStats[destinationName].classKind;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
copyStats[sourceName].useCount = 0;
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
if (destinationList.test(sourceName))
workList.set(sourceName);
destinationList.clear(destinationName);
}
destinationListSize = destinationList.getSize();
if (destinationListSize != 0) {
RegisterName sourceName = RegisterName(destinationList.getOne());
RegisterName destinationName;
if (!copyStats[sourceName].temporaryName) {
// Cycle problem.
RegisterClassKind classKind = copyStats[sourceName].classKind;
destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].temporaryName = destinationName;
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
} else
destinationName = copyStats[sourceName].temporaryName;
copyStats[sourceName].useCount = 0;
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
workList.set(sourceName);
}
}
nodeStackPtr->pushedList = pushedList;
nodeStackPtr->next = next;
nodeStackPtr->limit = limit;
++nodeStackPtr;
next = dGraph.getSuccessorsBegin(currentNode);
limit = dGraph.getSuccessorsEnd(currentNode);
}
}
}
#endif // _PHI_NODE_REMOVER_H_

View File

@@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocator.h"
#include "RegisterPressure.h"
#include "RegisterAllocatorTools.h"
#include "PhiNodeRemover.h"
#include "LiveRange.h"
#include "Liveness.h"
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
#include "Coalescing.h"
#include "Spilling.h"
#include "Coloring.h"
#include "Splits.h"
class Pool;
class ControlGraph;
class VirtualRegisterManager;
class InstructionEmitter;
UT_DEFINE_LOG_MODULE(RegAlloc);
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
// some special code for the high word annotation.
//
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
// Perform some tests on the instruction graph.
//
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
// Replace the phi node instructions by their equivalent copy instructions.
//
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
// Do the register allocation.
//
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
registerAllocator.doGraphColoring();
}
void RegisterAllocator::doGraphColoring()
{
// Initialize the liverange map.
//
initLiveRanges();
// Build the live ranges. We do this to compress the number of RegisterNames
// used in the insterference graph.
//
LiveRange<LowRegisterPressure>::build(*this);
// Remove unnecessary copies.
//
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
for (Uint8 loop = 0; loop < 10; loop++) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
while(true) {
// Build the interference graph.
//
iGraph.build();
// Coalesce the copy instructions.
//
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
break;
}
// Print the interference graph.
//
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Calculate the spill costs.
//
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
// Calculate the split costs.
//
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
// Build the live range graph.
//
lGraph.build();
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Color the graph. If it succeeds then we're done with the
// register allocation.
//
if (Coloring<LowRegisterPressure>::color(*this)) {
// Write the final colors in the instruction graph.
//
Coloring<LowRegisterPressure>::finalColoring(*this);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
return;
}
// We need to spill some registers.
//
Spilling<LowRegisterPressure>::insertSpillCode(*this);
// Insert the split instructions.
//
Splits<LowRegisterPressure>::insertSplitCode(*this);
// Update the live ranges.
//
// FIX
}
#ifdef DEBUG_LOG
RegisterAllocatorTools::updateInstructionGraph(*this);
RegisterAllocatorTools::printInstructions(*this);
#endif
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
abort();
}
void RegisterAllocator::initLiveRanges()
{
Uint32 count = this->nameCount;
RegisterName* name2range = new(pool) RegisterName[nameCount];
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
name2range[r] = r;
this->name2range = name2range;
rangeCount = count;
}

View File

@@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_ALLOCATOR_H_
#define _REGISTER_ALLOCATOR_H_
class Pool;
class ControlGraph;
class InstructionEmitter;
struct SpillCost;
struct SplitCost;
#include "Liveness.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h" // This should included by Backend.cpp
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
//template <class RegisterPressure>
class RegisterAllocator
{
public:
Pool& pool; //
ControlGraph& controlGraph; //
VirtualRegisterManager& vrManager; //
InstructionEmitter& emitter; //
RegisterName* name2range; //
RegisterName* color; //
SpillCost* spillCost; //
SparseSet* willSpill; //
SplitCost* splitCost; //
NameLinkedList** splitAround; //
InterferenceGraph<LowRegisterPressure> iGraph; //
LiveRangeGraph<LowRegisterPressure> lGraph; //
LivenessInfo<LowRegisterPressure> liveness; //
Uint32 nameCount; //
Uint32 rangeCount; //
bool splitFound; //
private:
//
//
void doGraphColoring();
public:
//
//
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
//
//
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
//
//
void initLiveRanges();
//
//
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
//
//
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
#endif // _REGISTER_ALLOCATOR_H_

View File

@@ -0,0 +1,355 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocatorTools.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "InstructionEmitter.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "Spilling.h"
#include "Splits.h"
#include "BitSet.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
#ifdef DEBUG
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
Uint32 nameCount = vrManager.getSize();
BitSet registerSeen(controlGraph.pool, nameCount);
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
}
bool renameRegisters = false;
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
renameRegisters = true;
fprintf(stderr,
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
" is never used nor defined by any instruction in the instruction graph\n"
" PLEASE FIX \n",
i);
}
if (renameRegisters) {
Instruction** definingInstruction = new Instruction*[nameCount];
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
RegisterName* newName = new RegisterName[nameCount];
memset(newName, '\0', nameCount * sizeof(RegisterName));
RegisterName nextName = RegisterName(1);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
}
vrManager.setSize(nextName);
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
for (Uint32 i = 1; i < nameCount; i++)
if (newName[i] != 0)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
delete newName;
delete definingInstruction;
}
}
#endif // DEBUG
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.advance(i);
if (instruction.getFlags() & ifCopy) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
if (source == destination)
instruction.remove();
}
}
}
}
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
}
}
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
if (!phiNodes.empty()) {
// Set the index of the incoming edges.
Uint32 index = 0;
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
predecessors.get(p).setIndex(index++);
// Insert the phi node instruction in the instruction list.
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
PhiNode& phiNode = phiNodes.get(i);
ValueKind kind = phiNode.getKind();
if (!isStorableKind(kind))
continue;
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
Uint32 nInputs = phiNode.nInputs();
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
node.addPhiNodeInstruction(phiNodeInstruction);
if (isDoublewordKind(kind)) {
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
node.addPhiNodeInstruction(phiNodeInstruction);
}
}
}
}
}
#ifdef DEBUG_LOG
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SpillCost* cost = registerAllocator.spillCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
if (cost[i].infinite)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
}
}
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SplitCost* cost = registerAllocator.splitCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
}
}
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
InstructionList& instructions = nodes[n]->getInstructions();
if (!phiNodes.empty()) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
phiNodes.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
if (!instructions.empty())
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
}
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
instructions.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,117 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
//
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
#define _REGISTER_ALLOCATOR_TOOLS_H_
#include "LogModule.h"
#include "RegisterTypes.h"
#include <string.h>
class RegisterAllocator;
class ControlGraph;
class InstructionEmitter;
class VirtualRegisterManager;
struct RegisterAllocatorTools
{
//
//
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
//
//
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
//
//
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
#ifdef DEBUG
//
//
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // DEBUG
#ifdef DEBUG_LOG
//
//
static void printInstructions(RegisterAllocator& registerAllocator);
//
//
static void printSpillCosts(RegisterAllocator& registerAllocator);
//
//
static void printSplitCosts(RegisterAllocator& registerAllocator);
#endif // DEBUG_LOG
};
//
// FIX: this should go in a class (LookupTable ?)
//
inline RegisterName findRoot(RegisterName name, RegisterName* table)
{
RegisterName* stack = table;
RegisterName* stackPtr = stack;
RegisterName newName;
while((newName = table[name]) != name) {
*--stackPtr = name;
name = newName;
}
while (stackPtr != stack)
table[*stackPtr++] = name;
return name;
}
inline void init(RegisterName* table, Uint32 nameCount)
{
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
table[r] = r;
}
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
{
RegisterName* liveRange = new RegisterName[tableSize];
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
// Update the lookup table.
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
findRoot(r, table);
// Count the liveranges.
Uint32 liveRangeCount = 1;
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
if (table[s] == s)
liveRange[s] = RegisterName(liveRangeCount++);
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
name2range[t] = liveRange[table[name2range[t]]];
return liveRangeCount;
}
inline double doLog10(Uint32 power)
{
double log = 1.0;
while (power--)
log *= 10.0;
return log;
}
#endif // _REGISTER_ALLOCATOR_TOOLS_H_

View File

@@ -16,27 +16,23 @@
* Reserved.
*/
#ifndef nsAddrBookSession_h___
#define nsAddrBookSession_h___
#ifndef _REGISTER_ASSIGNER_H_
#define _REGISTER_ASSIGNER_H_
#include "nsIAddrBookSession.h"
#include "nsISupports.h"
#include "nsVoidArray.h"
#include "Fundamentals.h"
#include "VirtualRegister.h"
class nsAddrBookSession : public nsIAddrBookSession
class FastBitMatrix;
class RegisterAssigner
{
public:
nsAddrBookSession();
virtual ~nsAddrBookSession();
NS_DECL_ISUPPORTS
NS_DECL_NSIADDRBOOKSESSION
protected:
nsVoidArray *mListeners;
nsFileSpec *mpUserDirectory;
VirtualRegisterManager& vRegManager;
public:
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
};
#endif /* nsAddrBookSession_h__ */
#endif /* _REGISTER_ASSIGNER_H_ */

View File

@@ -1,4 +1,4 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -12,17 +12,14 @@
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#ifndef _REGISTER_CLASS_H_
#define _REGISTER_CLASS_H_
#include "Fundamentals.h"
#include "RegisterTypes.h"
[scriptable, uuid(fe04c8e6-501e-11d3-a527-0060b0fc04b7)]
interface nsIAbAddressCollecter : nsISupports {
void CollectAddress(in string address);
};
#endif // _REGISTER_CLASS_H_

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -12,17 +12,26 @@
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "nsrootidl.idl"
#ifndef _REGISTER_PRESSURE_H_
#define _REGISTER_PRESSURE_H_
interface nsIAutoCompleteListener;
#include "BitSet.h"
#include "HashSet.h"
[scriptable, uuid(CA2A6B07-3625-11d3-988E-001083010E9B)]
interface nsIAutoCompleteSession : nsISupports {
void AutoComplete(in nsISupports aParam, in wstring aSearchString, in nsIAutoCompleteListener aResultListener);
struct LowRegisterPressure
{
typedef BitSet Set;
static const bool setIsOrdered = true;
};
struct HighRegisterPressure
{
typedef HashSet Set;
static const bool setIsOrdered = false;
};
#endif // _REGISTER_PRESSURE_H_

View File

@@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_TYPES_H_
#define _REGISTER_TYPES_H_
#include "Fundamentals.h"
//------------------------------------------------------------------------------
// RegisterName -
//
enum RegisterName {
rnInvalid = 0,
};
//------------------------------------------------------------------------------
// RegisterClassKind -
//
enum RegisterClassKind {
rckInvalid = 0,
rckGeneral,
rckStackSlot,
nRegisterClassKind
};
//------------------------------------------------------------------------------
// RegisterID -
//
enum RegisterID {
invalidID = 0
};
//------------------------------------------------------------------------------
// RegisterKind -
//
enum RegisterKind {
rkCallerSave = 0,
rkCalleeSave,
};
struct NameLinkedList {
RegisterName name;
NameLinkedList* next;
};
#ifdef DEBUG
const registerNameMask = 0x03ffffff;
const coloredRegisterMask = 0x04000000;
const machineRegisterMask = 0x08000000;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const coloredRegisterShift = 26;
const machineRegisterShift = 27;
const registerClassShift = 28;
#else // DEBUG
const registerNameMask = 0x0fffffff;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const registerClassShift = 28;
#endif // DEBUG
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
#ifdef DEBUG
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
#endif // DEBUG
#endif // _REGISTER_TYPES_H_

View File

@@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "SSATools.h"
#include "ControlGraph.h"
#include "VirtualRegister.h"
#include "Liveness.h"
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
if (!controlGraph.hasBackEdges)
return;
Liveness liveness(controlGraph.pool);
liveness.buildLivenessAnalysis(controlGraph, vrManager);
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -12,15 +12,18 @@
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "nsrootidl.idl"
#ifndef _SSA_TOOLS_H_
#define _SSA_TOOLS_H_
[scriptable, uuid(CA2A6B08-3625-11d3-988E-001083010E9B)]
interface nsIAutoCompleteListener : nsISupports {
void OnAutoCompleteResult(in nsISupports aParam, in wstring aOriginalString, in wstring aMatch);
};
#include "Fundamentals.h"
class ControlGraph;
class VirtualRegisterManager;
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // _SSA_TOOLS_H_

View File

@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "SparseSet.h"
#include "BitSet.h"
#include "Pool.h"
#ifdef DEBUG_LOG
// Print the set.
//
void SparseSet::printPretty(LogModuleObject log)
{
Pool pool;
BitSet set(pool, universeSize);
for (Uint32 i = 0; i < count; i++)
set.set(node[i].element);
set.printPretty(log);
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,168 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
//
#ifndef _SPARSE_SET_H_
#define _SPARSE_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "LogModule.h"
#include "BitSet.h"
class SparseSet
{
private:
struct Node {
Uint32 element;
Uint32 stackIndex;
};
Node* node;
Uint32 count;
Uint32 universeSize;
private:
// No copy constructor.
SparseSet(const SparseSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
// Clear the sparse set.
void clear() {count = 0;}
// Clear the element at index.
inline void clear(Uint32 index);
// Set the element at index.
inline void set(Uint32 index);
// Return true if the element at index is set.
inline bool test(Uint32 index) const;
// Union with the given sparse set.
inline void or(const SparseSet& set);
// Intersection with the given sparse set.
inline void and(const SparseSet& set);
// Difference with the given sparse set.
inline void difference(const SparseSet& set);
// Copy set.
inline SparseSet& operator = (const SparseSet& set);
inline SparseSet& operator = (const BitSet& set);
// Return true if the sparse sets are identical.
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
// Return true if the sparse sets are different.
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
// Logical operators.
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return the iterator for the first element of this set.
iterator begin() const {return count - 1;}
// Return the next iterator.
iterator advance(iterator pos) const {return --pos;}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos < 0;}
// Return the element for the given iterator;
Uint32 get(iterator pos) const {return node[pos].element;}
// Return one element of this set.
Uint32 getOne() const {assert(count > 0); return node[0].element;}
// Return the size of this set.
Uint32 getSize() const {return count;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
inline void SparseSet::clear(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex < count) && (node[stackIndex].element == element)) {
Uint32 stackTop = node[count - 1].element;
node[stackIndex].element = stackTop;
node[stackTop].stackIndex = stackIndex;
this->count = count - 1;
}
}
inline void SparseSet::set(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
node[count].element = element;
node[element].stackIndex = count;
this->count = count + 1;
}
}
inline bool SparseSet::test(Uint32 element) const
{
checkMember(element);
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
return ((stackIndex < count) && (node[stackIndex].element == element));
}
inline SparseSet& SparseSet::operator = (const SparseSet& set)
{
checkUniverseCompatibility(set);
Uint32 sourceCount = set.getSize();
Node* node = this->node;
memcpy(node, set.node, sourceCount * sizeof(Node));
for (Uint32 i = 0; i < sourceCount; i++) {
Uint32 element = node[i].element;
node[element].stackIndex = i;
}
count = sourceCount;
return *this;
}
inline SparseSet& SparseSet::operator = (const BitSet& set)
{
// FIX: there's room for optimization here.
assert(universeSize == set.getSize());
clear();
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
this->set(i);
return *this;
}
#endif // _SPARSE_SET_H_

View File

@@ -0,0 +1,270 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NEW_LAURENTM_CODE
#define INCLUDE_EMITTER
#include "CpuInfo.h"
#include "Fundamentals.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "Spilling.h"
void Spilling::
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
{
PRUint32 nVirtualRegisters = vRegManager.count();
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
RegisterFifo grNeedLoad(nVirtualRegisters);
RegisterFifo fpNeedLoad(nVirtualRegisters);
for (PRInt32 n = nNodes - 1; n >= 0; n--)
{
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
ControlNode& node = *dfsList[n];
currentLive = node.liveAtEnd;
PRUint32 nGeneralAlive = 0;
PRUint32 nFloatingPointAlive = 0;
// Get the number of registers alive at the end of this node.
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
if (vReg.spillInfo.willSpill)
{
currentLive.clear(j);
}
else
{
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
break;
default:
break;
}
}
}
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
{
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
InstructionDefine* defPtr;
// if(node.dfsNum == 8) { printf("\n");
// instruction.printPretty(stdout);
// printf("\n"); }
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
currentLive.clear(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive--;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive--;
break;
default:
break;
}
}
// Check for deaths
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
if (!currentLive.test(vReg.getRegisterIndex()))
// This is the last use of this register.
{
currentLive.set(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
{
PRUint32 toLoad = grNeedLoad.get();
currentLive.clear(toLoad);
nGeneralAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
{
PRUint32 toLoad = fpNeedLoad.get();
currentLive.clear(toLoad);
nFloatingPointAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
default:
break;
}
}
}
// Handle uses
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
PRUint32 registerIndex = vReg.getRegisterIndex();
if (vReg.spillInfo.willSpill) {
#if defined(GENERATE_FOR_X86)
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
switch (vReg.getClass())
{
case vrcInteger:
if (!grNeedLoad.test(registerIndex))
{
grNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/* if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
if (!fpNeedLoad.test(registerIndex))
{
fpNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/*if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
default:
break;
}
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
usedInThisInstruction.set(registerIndex);
vReg.spillInfo.lastUsingInstruction = &instruction;
}
currentLive.clear(registerIndex);
} else { // will not spill
currentLive.set(registerIndex);
}
}
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
if (vReg.spillInfo.willSpill)
#if defined(GENERATE_FOR_X86)
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
// this virtualRegister was used in this instruction and is also defined. We need to move
// this virtual register to its alias first and then save it to memory.
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
}
else
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg, *vReg.equivalentRegister[vrcStackSlot]);
}
}
}
}
while (!grNeedLoad.empty())
{
PRUint32 nl = grNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
while (!fpNeedLoad.empty())
{
PRUint32 nl = fpNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
}
}
#endif

View File

@@ -0,0 +1,269 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SPILLING_H_
#define _SPILLING_H_
#include "Fundamentals.h"
#include <string.h>
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
template <class RegisterPressure>
class Spilling
{
private:
static void insertStoreAfter(Instruction& instruction, RegisterName name);
static void insertLoadBefore(Instruction& instruction, RegisterName name);
public:
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
static void insertSpillCode(RegisterAllocator& registerAllocator);
};
struct SpillCost
{
double loads;
double stores;
double copies;
double cost;
bool infinite;
};
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet currentLive(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet& willSpill = *registerAllocator.willSpill;
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
needLoad.clear();
currentLive = liveOut[n];
mustSpill = currentLive;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.retreat(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
bool foundLiveDefine = false;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
foundLiveDefine = true;
break;
}
} else {
foundLiveDefine = true;
break;
}
if (defineBegin != defineEnd && !foundLiveDefine) {
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
instruction.remove();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
#ifdef DEBUG
if (needLoad.test(range))
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
abort();
}
#endif // DEBUG
if (willSpill.test(range))
insertStoreAfter(instruction, range);
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!currentLive.test(range))
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
RegisterName load = RegisterName(needLoad.get(r));
if (willSpill.test(load))
insertLoadBefore(instruction, load);
mustSpill.set(load);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
currentLive.set(range);
needLoad.set(range);
}
}
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
RegisterName load = RegisterName(needLoad.get(l));
if (willSpill.test(load))
insertLoadBefore(instructions.first(), load);
}
}
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert load for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert store for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet live(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
SpillCost* cost = new SpillCost[rangeCount];
memset(cost, '\0', rangeCount * sizeof(SpillCost));
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
needLoad.clear();
live = liveOut[n];
mustSpill = live;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
if (needLoad.test(range))
if (!mustSpill.test(range))
cost[range].infinite = true;
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
cost[range].stores += weight;
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
if (!live.test(name2range[usePtr->getRegisterName()])) {
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
Uint32 range = needLoad.get(l);
cost[range].loads += weight;
mustSpill.set(range);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
live.set(range);
needLoad.set(range);
}
if (instruction.getFlags() & ifCopy) {
assert(useBegin != useEnd && useBegin[0].isRegister());
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
RegisterName source = name2range[useBegin[0].getRegisterName()];
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
cost[source].copies += weight;
cost[destination].copies += weight;
}
}
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
cost[needLoad.get(s)].loads += weight;
}
for (Uint32 r = 0; r < rangeCount; r++) {
SpillCost& c = cost[r];
c.cost = 2 * (c.loads + c.stores) - c.copies;
}
registerAllocator.spillCost = cost;
}
#endif // _SPILLING_H_

View File

@@ -0,0 +1,239 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SPLITS_H_
#define _SPLITS_H_
#include "Fundamentals.h"
#include <string.h>
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
struct Splits
{
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
static void insertSplitCode(RegisterAllocator& registerAllocator);
};
struct SplitCost
{
double loads;
double stores;
};
template <class RegisterPressure>
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
{
// FIX
}
template <class RegisterPressure>
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
{
Pool& pool = registerAllocator.pool;
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >=0; --i) {
RegisterName neighbor = vector->neighbors[i];
RegisterName c = color[neighbor];
if (c < 6) { // FIX
NameLinkedList* node = new(pool) NameLinkedList();
node->name = neighbor;
node->next = neighborsWithColor[c];
neighborsWithColor[c] = node;
}
}
bool splitAroundName = true;
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
RegisterName bestColor = RegisterName(6); // FIX
double bestCost = registerAllocator.spillCost[range].cost;
SplitCost* splitCost = registerAllocator.splitCost;
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
double splitAroundNameCost = 0.0;
bool canSplitAroundName = true;
SplitCost& sCost = splitCost[range];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(neighbor, range)) {
canSplitAroundName = false;
break;
} else
splitAroundNameCost += addedCost;
}
if (canSplitAroundName && splitAroundNameCost < bestCost) {
bestCost = splitAroundNameCost;
bestColor = i;
splitAroundName = true;
}
double splitAroundColorCost = 0.0;
bool canSplitAroundColor = true;
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(range, neighbor)) {
canSplitAroundColor = false;
break;
} else {
SplitCost& sCost = splitCost[neighbor];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
splitAroundColorCost += addedCost;
}
}
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
bestCost = splitAroundColorCost;
bestColor = i;
splitAroundName = false;
}
}
if (bestColor < RegisterName(6)) {
color[range] = bestColor;
registerAllocator.splitFound = true;
NameLinkedList** splitAround = registerAllocator.splitAround;
if (splitAroundName)
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
newNode->name = node->name;
newNode->next = splitAround[range];
splitAround[range] = newNode;
}
else
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
RegisterName neighbor = node->name;
newNode->name = range;
newNode->next = splitAround[neighbor];
splitAround[neighbor] = newNode;
}
trespass("Found a split");
return true;
}
return false;
}
template <class RegisterPressure>
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
SparseSet live(pool, rangeCount);
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
live = liveOut[n];
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
ControlNode& successor = successorsPtr->getTarget();
if (successor.getControlKind() != ckEnd) {
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
RegisterName name = RegisterName(live.get(i));
if (!successorLiveIn.test(name))
splitCost[name].loads += doLog10(successor.loopDepth);
}
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!live.test(range)) {
if (&instruction != &instructions.last())
splitCost[range].loads += weight;
else {
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
}
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
live.set(name2range[usePtr->getRegisterName()]);
}
}
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
registerAllocator.splitAround = splitAround;
registerAllocator.splitCost = splitCost;
registerAllocator.splitFound = false;
}
#endif // _SPLITS_H_

View File

@@ -0,0 +1,186 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "HashTable.h"
#include "Timer.h"
#include "Pool.h"
static Pool pool; // Pool for the Timer class.
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
const nTimersInABlock = 128; // Number of timers in a block.
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
static Uint8 nextTimer = 0; // nextAvailableTimer.
//
// Calibrate the call to PR_Now().
//
static PRTime calibrate()
{
PRTime t = PR_Now();
PRTime& a = *new(pool) PRTime();
// Call 10 times the PR_Now() function.
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
t = (PR_Now() - t + 9) / 10;
return t;
}
static PRTime adjust = calibrate();
//
// Return the named timer..
//
TimerEntry& Timer::getTimerEntry(const char* name)
{
if (!timerEntries.exists(name)) {
TimerEntry* newEntry = new(pool) TimerEntry();
newEntry->accumulator = 0;
newEntry->running = false;
timerEntries.add(name, newEntry);
}
return *timerEntries[name];
}
//
// Return a reference to a new timer.
//
PRTime& Timer::getNewTimer()
{
if (nextTimer >= nTimersInABlock) {
timers = new(pool) PRTime[nTimersInABlock];
nextTimer = 0;
}
return timers[nextTimer++];
}
static Uint32 timersAreFrozen = 0;
//
// Start the named timer.
//
void Timer::start(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(!timer.running);
timer.accumulator = 0;
timer.running = true;
timer.done = false;
unfreezeTimers();
}
//
// Stop the named timer.
//
void Timer::stop(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.running);
timer.running = false;
timer.done = true;
unfreezeTimers();
}
//
// Freeze all the running timers.
//
void Timer::freezeTimers()
{
PRTime when = PR_Now() - adjust;
if (timersAreFrozen == 0) {
Vector<TimerEntry*> entries = timerEntries;
Uint32 count = entries.size();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.accumulator += (when - *entry.startTime);
}
}
}
timersAreFrozen++;
}
//
// Unfreeze all the running timers.
//
void Timer::unfreezeTimers()
{
PR_ASSERT(timersAreFrozen != 0);
timersAreFrozen--;
if (timersAreFrozen == 0) {
Vector<TimerEntry *> entries = timerEntries;
Uint32 count = entries.size();
PRTime& newStart = getNewTimer();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.startTime = &newStart;
}
}
newStart = PR_Now();
}
}
//
// Print the named timer in the file f.
//
void Timer::print(FILE* f, const char *name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.done);
PRTime elapsed = timer.accumulator;
if (elapsed >> 32) {
fprintf(f, "[timer %s out of range]\n", name);
} else {
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
}
fflush(f);
unfreezeTimers();
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include "Fundamentals.h"
#include "HashTable.h"
#include "prtime.h"
//
// Naming convention:
// As the class Timer contains only static methods, the timer's name should start with the
// module name. Otherwise starting 2 timers with the same name will assert.
//
#ifndef NO_TIMER
struct TimerEntry
{
PRTime *startTime; // Current time when we start the timer.
PRTime accumulator; // Time spent in this timer.
bool running; // True if the timer is running.
bool done; // True if the timer was running and was stopped.
};
class Timer
{
private:
// Return the named timer.
static TimerEntry& getTimerEntry(const char* name);
// Return a reference to a new Timer.
static PRTime& getNewTimer();
public:
// Start the timer.
static void start(const char* name);
// Stop the timer.
static void stop(const char* name);
// Freeze all the running timers.
static void freezeTimers();
// Unfreeze all the running timers.
static void unfreezeTimers();
// Print the timer.
static void print(FILE* f, const char *name);
};
inline void startTimer(const char* name) {Timer::start(name);}
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
#define START_TIMER_SAFE Timer::freezeTimers();
#define END_TIMER_SAFE Timer::unfreezeTimers();
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
#else /* NO_TIMER */
inline void startTimer(const char* /*name*/) {}
inline void stopTimer(const char* /*name*/) {}
#define START_TIMER_SAFE
#define END_TIMER_SAFE
#define TIMER_SAFE(x) x;
#endif /* NO_TIMER */
#endif /* _TIMER_H_ */

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -15,21 +15,26 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsICollection.idl"
[scriptable, uuid(013DD009-F73B-11d2-A2DA-001083003D0C)]
interface nsIAbBase : nsICollection {
#include "Fundamentals.h"
#include "VirtualRegister.h"
#include "Instruction.h"
readonly attribute string URI;
attribute string name;
//------------------------------------------------------------------------------
// VirtualRegister -
nsISupports GetChildNamed(in string name);
attribute nsIAbBase parent;
#ifdef MANUAL_TEMPLATES
template class IndexedPool<VirtualRegister>;
#endif
nsIEnumerator GetChildNodes();
// Set the defining instruction.
//
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
{
if (definingInstruction != NULL) {
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
return;
}
definingInstruction = &instruction;
}
void AddUnique(in nsISupports element);
void ReplaceElement(in nsISupports element, in nsISupports newElement);
};

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _VIRTUAL_REGISTER_H_
#define _VIRTUAL_REGISTER_H_
#include "Fundamentals.h"
#include "IndexedPool.h"
#include <string.h>
#include "RegisterTypes.h"
#include "RegisterClass.h"
//------------------------------------------------------------------------------
// VirtualRegister - 24b
class Instruction;
class VirtualRegister : public IndexedObject<VirtualRegister>
{
public:
Instruction* definingInstruction; // Instruction defining this VR.
// Initialize a VR of the given classKind.
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
// Return the defining instruction for this VR.
Instruction* getDefiningInstruction() const {return definingInstruction;}
// Set the defining instruction.
void setDefiningInstruction(Instruction& insn);
};
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
// they have the same index. If they have the same index then they are at the same
// address in the indexed pool.
//
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return &regA == &regB;}
//------------------------------------------------------------------------------
// VirtualRegisterManager -
struct PreColoredRegister
{
RegisterID id;
RegisterName color;
};
class VirtualRegisterManager
{
private:
IndexedPool<VirtualRegister> registerPool;
PreColoredRegister machineRegister[6];
public:
VirtualRegisterManager()
{
for (Uint32 i = 0; i < 6; i++)
machineRegister[i].id = invalidID;
}
// Return the VirtualRegister at the given index.
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
// Return a new VirtualRegister.
RegisterID newVirtualRegister(RegisterClassKind classKind)
{
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
RegisterID rid;
setName(rid, RegisterName(vReg.getIndex()));
setClass(rid, classKind);
return rid;
}
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
{
RegisterID rid = machineRegister[name].id;
if (rid == invalidID) {
rid = newVirtualRegister(classKind);
DEBUG_ONLY(setMachineRegister(rid));
machineRegister[name].id = rid;
machineRegister[name].color = name;
}
return rid;
}
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
// Return the VirtualRegister universe size.
Uint32 getSize() {return registerPool.getSize();}
void setSize(Uint32 size) {registerPool.setSize(size);}
};
#endif // _VIRTUAL_REGISTER_H_

View File

@@ -1,28 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src prefs build resources
include $(topsrcdir)/config/rules.mk

View File

@@ -1,17 +0,0 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
nsAbBaseCID.h

View File

@@ -1,49 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = addrbook
LIBRARY_NAME = addrbook
IS_COMPONENT = 1
CPPSRCS = nsAbFactory.cpp
EXPORTS = nsAbBaseCID.h
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libaddrbook_s.a \
$(DIST)/lib/librdfutil_s.a \
$(NULL)
EXTRA_DSO_LDOPTS = \
$(MKSHLIB_FORCE_ALL) \
$(SHARED_LIBRARY_LIBS) \
$(MKSHLIB_UNFORCE_ALL) \
-L$(DIST)/bin \
$(NSPR_LIBS) \
-lxpcom \
$(NULL)
include $(topsrcdir)/config/rules.mk
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile

View File

@@ -1,49 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
MODULE=addrbook
################################################################################
## exports
EXPORTS= \
nsAbBaseCID.h \
$(NULL)
################################################################################
## library
LIBNAME = .\$(OBJDIR)\addrbook
DLL = $(LIBNAME).dll
CPP_OBJS= \
.\$(OBJDIR)\nsAbFactory.obj \
$(NULL)
LLIBS= \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\addrbook_s.lib \
$(LIBNSPR) \
$(DIST)\lib\rdfutil_s.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin\components
$(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib

View File

@@ -1,154 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsAbBaseCID_h__
#define nsAbBaseCID_h__
#include "nsISupports.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
//
// nsAddressBook
//
#define NS_ADDRESSBOOK_PROGID \
"component://netscape/addressbook"
#define NS_ADDRESSBOOK_CID \
{ /* {D60B84F2-2A8C-11d3-9E07-00A0C92B5F0D} */ \
0xd60b84f2, 0x2a8c, 0x11d3, \
{ 0x9e, 0x7, 0x0, 0xa0, 0xc9, 0x2b, 0x5f, 0xd } \
}
//
// nsAbDirectoryDataSource
//
#define NS_ABDIRECTORYDATASOURCE_PROGID \
NS_RDF_DATASOURCE_PROGID_PREFIX "addressdirectory"
#define NS_ABDIRECTORYDATASOURCE_CID \
{ /* 0A79186D-F754-11d2-A2DA-001083003D0C */ \
0xa79186d, 0xf754, 0x11d2, \
{0xa2, 0xda, 0x0, 0x10, 0x83, 0x0, 0x3d, 0xc} \
}
//
// nsAbDirectory
//
#define NS_ABDIRECTORY_PROGID \
NS_RDF_RESOURCE_FACTORY_PROGID_PREFIX "abdirectory"
#define NS_ABDIRECTORY_CID \
{ /* {6C21831D-FCC2-11d2-A2E2-001083003D0C}*/ \
0x6c21831d, 0xfcc2, 0x11d2, \
{0xa2, 0xe2, 0x0, 0x10, 0x83, 0x0, 0x3d, 0xc} \
}
//
// nsAbCardDataSource
//
#define NS_ABCARDDATASOURCE_PROGID \
NS_RDF_DATASOURCE_PROGID_PREFIX "addresscard"
#define NS_ABCARDDATASOURCE_CID \
{ /* 1920E486-0709-11d3-A2EC-001083003D0C */ \
0x1920e486, 0x709, 0x11d3, \
{0xa2, 0xec, 0x0, 0x10, 0x83, 0x0, 0x3d, 0xc} \
}
//
// nsAbCard
//
#define NS_ABCARD_PROGID \
NS_RDF_RESOURCE_FACTORY_PROGID_PREFIX "abcard"
#define NS_ABCARD_CID \
{ /* {1920E487-0709-11d3-A2EC-001083003D0C}*/ \
0x1920e487, 0x709, 0x11d3, \
{0xa2, 0xec, 0x0, 0x10, 0x83, 0x0, 0x3d, 0xc} \
}
//
// nsAddressBookDB
//
#define NS_ADDRDATABASE_PROGID \
"component://netscape/addressbook/carddatabase"
#define NS_ADDRDATABASE_CID \
{ /* 63187917-1D19-11d3-A302-001083003D0C */ \
0x63187917, 0x1d19, 0x11d3, \
{0xa3, 0x2, 0x0, 0x10, 0x83, 0x0, 0x3d, 0xc} \
}
//
// nsAbCardProperty
//
#define NS_ABCARDPROPERTY_PROGID \
"component://netscape/addressbook/cardproperty"
#define NS_ABCARDPROPERTY_CID \
{ /* 2B722171-2CEA-11d3-9E0B-00A0C92B5F0D */ \
0x2b722171, 0x2cea, 0x11d3, \
{0x9e, 0xb, 0x0, 0xa0, 0xc9, 0x2b, 0x5f, 0xd} \
}
//
// nsAddrBookSession
//
#define NS_ADDRBOOKSESSION_PROGID \
"component://netscape/addressbook/services/session"
#define NS_ADDRBOOKSESSION_CID \
{ /* C5339442-303F-11d3-9E13-00A0C92B5F0D */ \
0xc5339442, 0x303f, 0x11d3, \
{0x9e, 0x13, 0x0, 0xa0, 0xc9, 0x2b, 0x5f, 0xd} \
}
//
// nsAbDirProperty
//
#define NS_ABDIRPROPERTY_PROGID \
"component://netscape/addressbook/directoryproperty"
#define NS_ABDIRPROPERTY_CID \
{ /* 6FD8EC67-3965-11d3-A316-001083003D0C */ \
0x6fd8ec67, 0x3965, 0x11d3, \
{0xa3, 0x16, 0x0, 0x10, 0x83, 0x0, 0x3d, 0xc} \
}
//
// nsAbAutoCompleteSession
//
#define NS_ABAUTOCOMPLETESESSION_PROGID \
"component://netscape/messenger/autocomplete&type=addrbook"
#define NS_ABAUTOCOMPLETESESSION_CID \
{ /* 138DE9BD-362B-11d3-988E-001083010E9B */ \
0x138de9bd, 0x362b, 0x11d3, \
{0x98, 0x8e, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b} \
}
//
// nsAbAddressCollecter
//
#define NS_ABADDRESSCOLLECTER_PROGID \
"component://netscape/addressbook/services/addressCollecter"
#define NS_ABADDRESSCOLLECTER_CID \
{ /* fe04c8e6-501e-11d3-a527-0060b0fc04b7 */ \
0xfe04c8e6, 0x501e, 0x11d3, \
{0xa5, 0x27, 0x0, 0x60, 0xb0, 0xfc, 0x4, 0xb7} \
}
#endif // nsAbBaseCID_h__

View File

@@ -1,83 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998,1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsAbBaseCID.h"
#include "pratom.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "rdf.h"
#include "nsCRT.h"
#include "nsCOMPtr.h"
/* Include all of the interfaces our factory can generate components for */
#include "nsDirectoryDataSource.h"
#include "nsCardDataSource.h"
#include "nsAbDirectory.h"
#include "nsAbCard.h"
#include "nsAddrDatabase.h"
#include "nsAddressBook.h"
#include "nsAddrBookSession.h"
#include "nsAbDirProperty.h"
#include "nsAbAutoCompleteSession.h"
#include "nsAbAddressCollecter.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAddressBook)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAbDirectoryDataSource,Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirectory)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAbCardDataSource,Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbCard)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbCardProperty)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAddrDatabase)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirProperty)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAddrBookSession)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbAutoCompleteSession)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbAddressCollecter)
struct components_t {
nsCID cid;
nsIGenericFactory::ConstructorProcPtr constructor;
const char *progid;
const char *description;
};
static components_t components[] =
{
{ NS_ADDRESSBOOK_CID, &nsAddressBookConstructor, NS_ADDRESSBOOK_PROGID, },
{ NS_ABDIRECTORYDATASOURCE_CID, &nsAbDirectoryDataSourceConstructor, NS_ABDIRECTORYDATASOURCE_PROGID, },
{ NS_ABDIRECTORY_CID, &nsAbDirectoryConstructor, NS_ABDIRECTORY_PROGID, },
{ NS_ABCARDDATASOURCE_CID, &nsAbCardDataSourceConstructor, NS_ABCARDDATASOURCE_PROGID, },
{ NS_ABCARD_CID, &nsAbCardConstructor, NS_ABCARD_PROGID, },
{ NS_ADDRDATABASE_CID, &nsAddrDatabaseConstructor, NS_ADDRDATABASE_PROGID, },
{ NS_ABCARDPROPERTY_CID, &nsAbCardPropertyConstructor, NS_ABCARDPROPERTY_PROGID, },
{ NS_ABDIRPROPERTY_CID, &nsAbDirPropertyConstructor, NS_ABDIRPROPERTY_PROGID, },
{ NS_ADDRBOOKSESSION_CID, &nsAddrBookSessionConstructor, NS_ADDRBOOKSESSION_PROGID, },
{ NS_ABAUTOCOMPLETESESSION_CID, &nsAbAutoCompleteSessionConstructor, NS_ABAUTOCOMPLETESESSION_PROGID, },
{ NS_ABADDRESSCOLLECTER_CID, &nsAbAddressCollecterConstructor, NS_ABADDRESSCOLLECTER_PROGID, },
};
NS_IMPL_MODULE(components)
NS_IMPL_NSGETMODULE(nsModule)

View File

@@ -1,22 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..
DIRS=public src prefs build resources
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,28 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = resources
include $(topsrcdir)/config/rules.mk

View File

@@ -1,22 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
DIRS= resources
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,28 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = content locale
include $(topsrcdir)/config/rules.mk

View File

@@ -1,19 +0,0 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# This is a list of local files which get copied to the res\mailnews\messenger directory
#
pref-addressing.xul

View File

@@ -1,37 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
SAMPLES_DIR = $(DIST)/bin/chrome/addressbook/content/default
EXPORT_RESOURCE_SAMPLES = \
pref-addressing.xul \
$(NULL)
include $(topsrcdir)/config/rules.mk
GARBAGE += $(addprefix $(SAMPLES_DIR)/, $(EXPORT_RESOURCE_SAMPLES))
install::
$(INSTALL) $(addprefix $(srcdir)/, $(EXPORT_RESOURCE_SAMPLES)) $(SAMPLES_DIR)

View File

@@ -1,26 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..\..
include <$(DEPTH)\config\rules.mak>
install::
$(MAKE_INSTALL) pref-addressing.xul $(DIST)\bin\chrome\addressbook\content\default
clobber::
rm -f $(DIST)\chrome\addressbook\content\default\pref-addressing.xul

View File

@@ -1,66 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://pref/skin/pref.css" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/pref-addressing.dtd">
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="StartUp('Mailnews-Main')" >
<html:script language="javascript" src="chrome://pref/content/PrefsWindow.js"/>
<html:div flex="100%">
<html:div id="top">
<html:span id="lefttext">&pane.title;</html:span>
</html:div>
&pinpoint.label;
<html:form>
<html:table>
<html:tr><html:td>&lookFor.label;</html:td></html:tr>
<html:tr><html:td>
<html:input type="checkbox"/>
<html:label>&padCheck.label;</html:label>
</html:td></html:tr>
<html:tr><html:td>
<html:input type="checkbox"/>
<html:label>&dirCheck.label;</html:label>
</html:td></html:tr>
<html:tr><html:td>
<html:select>
<html:option>&nsbook.label;</html:option>
</html:select>
</html:td></html:tr>
<html:tr><html:td>&mulFound.label;</html:td></html:tr>
<html:tr><html:td>
<html:input name="multilist" type="radio"/>
<html:label>&showList.label;</html:label>
</html:td></html:tr>
<html:tr><html:td>
<html:input name="multilist" type="radio"/>
<html:label>&acceptList.label;</html:label>
</html:td></html:tr>
<html:tr><html:td>&oneMatch.label;</html:td></html:tr>
<html:tr><html:td>
<html:input type="checkbox"/>
<html:label>&useAddress.label;</html:label>
</html:td></html:tr>
</html:table>
</html:form>
&displayFullname.label;
<html:form>
<html:table>
<html:tr><html:td>
<html:input name="displayname" type="radio" id="pref:0:int:mail.addr_book.lastnamefirst" checked="true"/>
<html:label>&useDisplayName.label;</html:label>
</html:td></html:tr>
<html:tr><html:td>
<html:input name="displayname" type="radio" id="pref:1:int:mail.addr_book.lastnamefirst"/>
<html:label>&useLastFirst.label;</html:label>
</html:td></html:tr>
</html:table>
</html:form>
</html:div>
</window>

View File

@@ -1,28 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = en-US
include $(topsrcdir)/config/rules.mk

View File

@@ -1 +0,0 @@
pref-addressing.dtd

View File

@@ -1,29 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
install::
$(INSTALL) $(srcdir)/pref-addressing.dtd $(DIST)/bin/chrome/addressbook/locale/en-US

View File

@@ -1,29 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..\..\..
include <$(DEPTH)\config\rules.mak>
DISTBROWSER=$(DIST)\bin\chrome\addressbook\locale\en-US
install::
$(MAKE_INSTALL) pref-addressing.dtd $(DISTBROWSER)
clobber::
rm -f $(DIST)\bin\chrome\addressbook\locale\en-US\pref-addressing.dtd

View File

@@ -1,35 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!ENTITY window.title "Addressing">
<!ENTITY pane.title "Addressing">
<!ENTITY pinpoint.label "Pinpoint Addressing">
<!ENTITY lookFor.label "Look for addresses in the following">
<!ENTITY padCheck.label "Address Books">
<!ENTITY dirCheck.label "Directory Server">
<!ENTITY nsbook.label "Netscape Phonebook">
<!ENTITY mulFound.label "When there are multiple addresses found:">
<!ENTITY showList.label "Show me a list of choices">
<!ENTITY acceptList.label "Accept what I have typed">
<!ENTITY oneMatch.label "If there is one match in your personal address books:">
<!ENTITY useAddress.label "Use the address and do not search in the directory">
<!ENTITY displayFullname.label "When displaying full names:">
<!ENTITY useDisplayName.label "Show names using display name (from address book card)">
<!ENTITY useLastFirst.label "Show names using last name, first name">

View File

@@ -1,22 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..\..
DIRS= en-US
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,22 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..
DIRS= content locale
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,18 +0,0 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# This is a list of local files which get copied to the mozilla:dist:mailnews directory
#

View File

@@ -1,6 +0,0 @@
#
# This is a list of local files which get copied to the mozilla:dist:idl directory
#
nsIAbAddressCollecter.idl

View File

@@ -1,43 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = addrbook
XPIDLSRCS = \
nsIAbListener.idl \
nsIAbDirectory.idl \
nsIAbCard.idl \
nsIAddrDBAnnouncer.idl \
nsIAddrDBListener.idl \
nsIAddrDatabase.idl \
nsIAddressBook.idl \
nsIAbBase.idl \
nsIAddrBookSession.idl \
nsIAutoCompleteListener.idl \
nsIAutoCompleteSession.idl \
nsIAbAddressCollecter.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,39 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
MODULE=addrbook
XPIDLSRCS = \
.\nsIAbListener.idl \
.\nsIAbBase.idl \
.\nsIAbDirectory.idl \
.\nsIAbCard.idl \
.\nsIAddrDBAnnouncer.idl \
.\nsIAddrDBListener.idl \
.\nsIAddrDatabase.idl \
.\nsIAddressBook.idl \
.\nsIAddrBookSession.idl \
.\nsIAutoCompleteSession.idl \
.\nsIAutoCompleteListener.idl \
.\nsIAbAddressCollecter.idl \
$(NULL)
include <$(DEPTH)\config\rules.mak>
include <$(DEPTH)\config\config.mak>

View File

@@ -1,97 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
interface nsIAddrDatabase;
[ptr] native nsVoidArray(nsVoidArray);
%{C++
#include "nsVoidArray.h"
%}
[scriptable, uuid(FA5C977F-04C8-11d3-A2EB-001083003D0C)]
interface nsIAbCard : nsISupports {
attribute wstring FirstName;
attribute wstring LastName;
attribute wstring DisplayName;
attribute wstring NickName;
attribute wstring PrimaryEmail;
attribute wstring SecondEmail;
attribute wstring WorkPhone;
attribute wstring HomePhone;
attribute wstring FaxNumber;
attribute wstring PagerNumber;
attribute wstring CellularNumber;
attribute wstring HomeAddress;
attribute wstring HomeAddress2;
attribute wstring HomeCity;
attribute wstring HomeState;
attribute wstring HomeZipCode;
attribute wstring HomeCountry;
attribute wstring WorkAddress;
attribute wstring WorkAddress2;
attribute wstring WorkCity;
attribute wstring WorkState;
attribute wstring WorkZipCode;
attribute wstring WorkCountry;
attribute wstring JobTitle;
attribute wstring Department;
attribute wstring Company;
attribute wstring WebPage1;
attribute wstring WebPage2;
attribute wstring BirthYear;
attribute wstring BirthMonth;
attribute wstring BirthDay;
attribute wstring Custom1;
attribute wstring Custom2;
attribute wstring Custom3;
attribute wstring Custom4;
attribute wstring Notes;
attribute unsigned long LastModifiedDate;
attribute boolean SendPlainText;
attribute unsigned long DbTableID;
attribute unsigned long DbRowID;
void GetCardValue(in string attrname, out wstring value);
void SetCardValue(in string attrname, in wstring value);
void SetAbDatabase(in nsIAddrDatabase database);
[noscript] void GetAnonymousStrAttrubutesList(out nsVoidArray attrlist);
[noscript] void GetAnonymousStrValuesList(out nsVoidArray valuelist);
[noscript] void GetAnonymousIntAttrubutesList(out nsVoidArray attrlist);
[noscript] void GetAnonymousIntValuesList(out nsVoidArray valuelist);
[noscript] void GetAnonymousBoolAttrubutesList(out nsVoidArray attrlist);
[noscript] void GetAnonymousBoolValuesList(out nsVoidArray valuelist);
void SetAnonymousStringAttribute(in string attrname, in string value);
void SetAnonymousIntAttribute(in string attrname, in unsigned long value);
void SetAnonymousBoolAttribute(in string attrname, in boolean value);
void AddAnonymousAttributesToDB();
void EditAnonymousAttributesInDB();
void GetCardURI(out string uri);
void AddCardToDatabase(in string uri);
void EditCardToDatabase(in string uri);
void CopyCard(in nsIAbCard srcCard);
void GetCollationKey(in wstring str, out wstring key);
};

View File

@@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "nsIAbCard.idl"
#include "nsISupportsArray.idl"
[ptr] native nsFileSpec(nsFileSpec);
[ptr] native DIR_Server(DIR_Server);
%{C++
#include "nsFileSpec.h"
#include "nsDirPrefs.h"
%}
[scriptable, uuid(1920E485-0709-11d3-A2EC-001083003D0C)]
interface nsIAbDirectory : nsISupports {
attribute wstring DirName;
attribute unsigned long LastModifiedDate;
attribute DIR_Server server;
void GetDirFilePath(out string dbPath);
void GetChildNodes(out nsIEnumerator childList);
void GetChildCards(out nsIEnumerator childCards);
void AddChildCards(in string uriName, out nsIAbCard childCard);
void AddDirectory(in string uriName, out nsIAbDirectory childDir);
void DeleteDirectories(in nsISupportsArray dierctories);
void DeleteCards(in nsISupportsArray cards);
void HasCard(in nsIAbCard cards, out boolean hasCard);
void HasDirectory(in nsIAbDirectory dir, out boolean hasDir);
void GetMailingList(out nsIEnumerator mailingList);
void CreateNewDirectory(in wstring dirName, in string fileName);
void GetDirUri(out string uri);
};

View File

@@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "nsIEnumerator.idl"
[scriptable, uuid(1920E484-0709-11d3-A2EC-001083003D0C)]
interface nsIAbListener : nsISupports {
void OnItemAdded(in nsISupports parentDir, in nsISupports item);
void OnItemRemoved(in nsISupports parentDir, in nsISupports item);
void OnItemPropertyChanged(in nsISupports item, in string property, in wstring oldValue, in wstring newValue);
};

View File

@@ -1,49 +0,0 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
/*
* The mail session is a replacement for the old 4.x MSG_Master object. It
* contains mail session generic information such as the account manager, etc
* I'm starting this off as an empty interface and as people feel they need to
* add more information to it, they can. I think this is a better approach
* than trying to port over the old MSG_Master in its entirety as that had a
* lot of cruft in it....
*/
#include "nsISupports.idl"
#include "nsIAbListener.idl"
#include "nsIAbDirectory.idl"
#include "nsIAbCard.idl"
[scriptable, uuid(C5339441-303F-11d3-9E13-00A0C92B5F0D)]
interface nsIAddrBookSession : nsISupports {
void AddAddressBookListener(in nsIAbListener listener);
void RemoveAddressBookListener(in nsIAbListener listener);
void NotifyItemPropertyChanged(in nsISupports item,
in string property,
in wstring oldValue,
in wstring newValue);
void NotifyDirectoryItemAdded(in nsIAbDirectory directory, in nsISupports item);
void NotifyDirectoryItemDeleted(in nsIAbDirectory directory, in nsISupports item);
[noscript] void GetUserProfileDirectory(out nsFileSpec userDir);
};

View File

@@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "nsIAbCard.idl"
interface nsIAddrDBListener;
[scriptable, uuid(A4186D8A-1DD0-11d3-A303-001083003D0C)]
interface nsIAddrDBAnnouncer : nsISupports {
void AddListener(in nsIAddrDBListener listener);
void RemoveListener(in nsIAddrDBListener listener);
void NotifyCardAttribChange(in unsigned long abCode,
in nsIAddrDBListener instigator);
void NotifyCardEntryChange (in unsigned long abCode,
in nsIAbCard card,
in nsIAddrDBListener instigator);
void NotifyAnnouncerGoingAway();
};

View File

@@ -1,32 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "nsIAbCard.idl"
interface nsIAddrDBAnnouncer;
[scriptable, uuid(A4186D89-1DD0-11d3-A303-001083003D0C)]
interface nsIAddrDBListener : nsISupports {
void OnCardAttribChange(in unsigned long abCode,
in nsIAddrDBListener instigator);
void OnCardEntryChange (in unsigned long abCode,
in nsIAbCard card,
in nsIAddrDBListener instigator);
void OnAnnouncerGoingAway(in nsIAddrDBAnnouncer instigator);
};

View File

@@ -1,109 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* nsFileSpec is declared in nsIAbDirectory.idl */
#include "nsIAddrDBAnnouncer.idl"
#include "nsIAbCard.idl"
#include "nsIAbDirectory.idl"
[ptr] native nsIMdbTableRowCursor(nsIMdbTableRowCursor);
[ptr] native nsIMdbEnv(nsIMdbEnv);
[ptr] native nsIMdbRow(nsIMdbRow);
%{C++
#include "mdb.h"
%}
[scriptable, uuid(A4186D8B-1DD0-11d3-A303-001083003D0C)]
interface nsIAddrDatabase : nsIAddrDBAnnouncer {
attribute nsFileSpec dbPath;
[noscript] void Open(in nsFileSpec folderName, in boolean create,
out nsIAddrDatabase pCardDB, in boolean upgrading);
void Close(in boolean forceCommit);
[noscript] void OpenMDB(in nsFileSpec dbName, in boolean create);
void CloseMDB(in boolean commit);
void OpenAnonymousDB(out nsIAddrDatabase pCardDB);
void CloseAnonymousDB(in boolean forceCommit);
void Commit(in unsigned long commitType);
void ForceClosed();
void CreateNewCardAndAddToDB(in nsIAbCard newCard, in boolean beNotify);
void EnumerateCards(in nsIAbDirectory directory, out nsIEnumerator result);
void EnumerateMailingLists(in nsIAbDirectory directory, out nsIEnumerator result);
void DeleteCard(in nsIAbCard card, in boolean beNotify);
void EditCard(in nsIAbCard card, in boolean beNotify);
void ContainsCard(in nsIAbCard card, out boolean hasCard);
void GetCardForEmailAddress(in nsIAbDirectory directory, in string emailAddress, out nsIAbCard card);
void SetAnonymousStringAttribute(in string attrname, in string value);
void GetAnonymousStringAttribute(in string attrname, out string value);
void SetAnonymousIntAttribute(in string attrname, in unsigned long value);
void GetAnonymousIntAttribute(in string attrname, out unsigned long value);
void SetAnonymousBoolAttribute(in string attrname, in boolean value);
void GetAnonymousBoolAttribute(in string attrname, out boolean value);
void AddAnonymousAttributesToDB();
void RemoveAnonymousAttributesFromDB();
void EditAnonymousAttributesInDB();
void AddAnonymousAttributesFromCard(in nsIAbCard card);
void RemoveAnonymousAttributesFromCard(in nsIAbCard card);
void EditAnonymousAttributesFromCard(in nsIAbCard card);
[noscript] void GetNewRow(out nsIMdbRow newRow);
[noscript] void AddCardRowToDB(in nsIMdbRow newRow);
[noscript] void AddFirstName(in nsIMdbRow row, in string value);
[noscript] void AddLastName(in nsIMdbRow row, in string value);
[noscript] void AddDisplayName(in nsIMdbRow row, in string value);
[noscript] void AddNickName(in nsIMdbRow row, in string value);
[noscript] void AddPrimaryEmail(in nsIMdbRow row, in string value);
[noscript] void Add2ndEmail(in nsIMdbRow row, in string value);
[noscript] void AddWorkPhone(in nsIMdbRow row, in string value);
[noscript] void AddHomePhone(in nsIMdbRow row, in string value);
[noscript] void AddFaxNumber(in nsIMdbRow row, in string value);
[noscript] void AddPagerNumber(in nsIMdbRow row, in string value);
[noscript] void AddCellularNumber(in nsIMdbRow row, in string value);
[noscript] void AddHomeAddress(in nsIMdbRow row, in string value);
[noscript] void AddHomeAddress2(in nsIMdbRow row, in string value);
[noscript] void AddHomeCity(in nsIMdbRow row, in string value);
[noscript] void AddHomeState(in nsIMdbRow row, in string value);
[noscript] void AddHomeZipCode(in nsIMdbRow row, in string value);
[noscript] void AddHomeCountry(in nsIMdbRow row, in string value);
[noscript] void AddWorkAddress(in nsIMdbRow row, in string value);
[noscript] void AddWorkAddress2(in nsIMdbRow row, in string value);
[noscript] void AddWorkCity(in nsIMdbRow row, in string value);
[noscript] void AddWorkState(in nsIMdbRow row, in string value);
[noscript] void AddWorkZipCode(in nsIMdbRow row, in string value);
[noscript] void AddWorkCountry(in nsIMdbRow row, in string value);
[noscript] void AddJobTitle(in nsIMdbRow row, in string value);
[noscript] void AddDepartment(in nsIMdbRow row, in string value);
[noscript] void AddCompany(in nsIMdbRow row, in string value);
[noscript] void AddWebPage1(in nsIMdbRow row, in string value);
[noscript] void AddWebPage2(in nsIMdbRow row, in string value);
[noscript] void AddBirthYear(in nsIMdbRow row, in string value);
[noscript] void AddBirthMonth(in nsIMdbRow row, in string value);
[noscript] void AddBirthDay(in nsIMdbRow row, in string value);
[noscript] void AddCustom1(in nsIMdbRow row, in string value);
[noscript] void AddCustom2(in nsIMdbRow row, in string value);
[noscript] void AddCustom3(in nsIMdbRow row, in string value);
[noscript] void AddCustom4(in nsIMdbRow row, in string value);
[noscript] void AddNotes(in nsIMdbRow row, in string value);
};

View File

@@ -1,43 +0,0 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISupports.idl"
#include "xulstubs.idl"
#include "nsIRDFCompositeDataSource.idl"
#include "nsIAbCard.idl"
%{C++
#include "nsIDOMNodeList.h"
#include "nsIDOMXULElement.h"
%}
interface nsIDOMWindow;
[scriptable, uuid(D60B84F1-2A8C-11d3-9E07-00A0C92B5F0D)]
interface nsIAddressBook : nsISupports {
void DeleteCards(in nsIDOMXULElement tree, in nsIDOMXULElement srcDir, in nsIDOMNodeList node);
void NewAddressBook(in nsIRDFCompositeDataSource db, in nsIDOMXULElement srcDir, in wstring name);
void DeleteAddressBooks(in nsIRDFCompositeDataSource db, in nsIDOMXULElement srcDir, in nsIDOMNodeList node);
void PrintCard();
void PrintAddressbook();
void SetWebShellWindow(in nsIDOMWindow win);
void ImportAddressBook();
};

View File

@@ -1,28 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = content locale skin
include $(topsrcdir)/config/rules.mk

View File

@@ -1,33 +0,0 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# This is a list of local files which get copied to the res\mailnews\messenger directory
#
abAddressBookNameDialog.js
abAddressBookNameDialog.xul
abCardOverlay.js
abCardOverlay.xul
abCardViewOverlay.js
abCardViewOverlay.xul
abCommon.js
abDirTreeOverlay.xul
abEditCardDialog.xul
abNewCardDialog.xul
abResultsTreeOverlay.xul
abSelectAddressesDialog.js
abSelectAddressesDialog.xul
addressbook.js
addressbook.xul

View File

@@ -1,51 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
SAMPLES_DIR = $(DIST)/bin/chrome/addressbook/content/default
EXPORT_RESOURCE_SAMPLES = \
abAddressBookNameDialog.js \
abAddressBookNameDialog.xul \
abCardOverlay.js \
abCardOverlay.xul \
abCardViewOverlay.js \
abCardViewOverlay.xul \
abCommon.js \
abDirTreeOverlay.xul \
abEditCardDialog.xul \
abNewCardDialog.xul \
abResultsTreeOverlay.xul \
abSelectAddressesDialog.js \
abSelectAddressesDialog.xul \
addressbook.js \
addressbook.xul \
$(NULL)
include $(topsrcdir)/config/rules.mk
GARBAGE += $(addprefix $(SAMPLES_DIR)/, $(EXPORT_RESOURCE_SAMPLES))
install::
$(INSTALL) $(addprefix $(srcdir)/, $(EXPORT_RESOURCE_SAMPLES)) $(SAMPLES_DIR)

View File

@@ -1,37 +0,0 @@
var okCallback = 0;
function abNameOnLoad()
{
doSetOKCancel(abNameOKButton, 0);
// look in arguments[0] for parameters
if (window.arguments && window.arguments[0])
{
if ( window.arguments[0].title )
{
dump("title = " + window.arguments[0].title + "\n");
var title = window.arguments[0].title;
top.window.title = title;
}
if ( window.arguments[0].okCallback )
top.okCallback = window.arguments[0].okCallback;
}
// focus on input
var name = document.getElementById('name');
if ( name )
name.focus();
}
function abNameOKButton()
{
if ( top.okCallback )
{
var name = document.getElementById('name').value;
top.okCallback(name);
}
return true;
}

View File

@@ -1,51 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abAddressBookNameDialog.dtd">
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
align="vertical"
class="dialog"
onload="abNameOnLoad()"
style="padding:10px">
<html:script language="JavaScript" src="chrome://addressbook/content/abAddressBookNameDialog.js"/>
<keyset id="keyset"/>
<box align="vertical" style="width:36em; min-height:12em">
<spring flex="100%"/>
<html:div style="margin-bottom:.3em">&name.label;</html:div>
<html:input tabindex="0" type="text" id="name" style="width:100%"/>
<spring flex="100%"/>
<box id="okCancelButtons"/>
</box>
</window>

View File

@@ -1,303 +0,0 @@
var editCard;
var newCardTitlePrefix = "New Card for ";
var editCardTitlePrefix = "Card for ";
var editCardFirstLastSeparator = " ";
var editCardLastFirstSeparator = ", ";
function OnLoadNewCard()
{
InitEditCard();
doSetOKCancel(NewCardOKButton, 0);
editCard.card = 0;
editCard.okCallback = 0;
editCard.titlePrefix = newCardTitlePrefix;
if (window.arguments && window.arguments[0])
{
if ( window.arguments[0].selectedAB )
editCard.selectedAB = window.arguments[0].selectedAB;
}
// set popup with address book names
var abPopup = document.getElementById('abPopup');
if ( editCard.selectedAB )
abPopup.value = editCard.selectedAB;
//// FIX ME - looks like we need to focus on both the text field and the tab widget
//// probably need to do the same in the addressing widget
// focus on first name
var firstName = document.getElementById('FirstName');
if ( firstName )
firstName.focus();
}
function OnLoadEditCard()
{
InitEditCard();
doSetOKCancel(EditCardOKButton, 0);
editCard.titlePrefix = editCardTitlePrefix;
if (window.arguments && window.arguments[0])
{
if ( window.arguments[0].card )
editCard.card = window.arguments[0].card;
if ( window.arguments[0].okCallback )
editCard.okCallback = window.arguments[0].okCallback;
if ( window.arguments[0].abURI )
editCard.abURI = window.arguments[0].abURI;
}
// set global state variables
// if first or last name entered, disable generateDisplayName
if ( editCard.generateDisplayName && (editCard.card.FirstName.length +
editCard.card.LastName.length +
editCard.card.DisplayName.length > 0) )
{
editCard.generateDisplayName = false;
}
GetCardValues(editCard.card, document);
top.window.title = editCard.titlePrefix + editCard.card.DisplayName;
}
function InitEditCard()
{
// create editCard object that contains global variables for editCard.js
editCard = new Object;
// get pointer to nsIPref object
var prefs = Components.classes["component://netscape/preferences"];
if ( prefs )
{
prefs = prefs.getService();
if ( prefs )
{
prefs = prefs.QueryInterface(Components.interfaces.nsIPref);
editCard.prefs = prefs;
}
}
// get specific prefs that editCard will need
if ( prefs )
{
try {
editCard.displayLastNameFirst = prefs.GetBoolPref("mail.addr_book.lastnamefirst");
}
catch (ex) {
dump("failed to get the mail.addr_book.lastnamefirst pref\n");
}
try {
editCard.generateDisplayName = prefs.GetBoolPref("mail.addr_book.displayName.autoGeneration");
}
catch (ex) {
dump("failed to get the mail.addr_book.displayName.autoGeneration pref\n");
}
}
}
function NewCardOKButton()
{
var popup = document.getElementById('abPopup');
if ( popup )
{
var uri = popup.value;
// FIX ME - hack to avoid crashing if no ab selected because of blank option bug from template
// should be able to just remove this if we are not seeing blank lines in the ab popup
if ( !uri )
return false; // don't close window
// -----
var cardproperty = Components.classes["component://netscape/addressbook/cardproperty"].createInstance();
cardproperty = cardproperty.QueryInterface(Components.interfaces.nsIAbCard);
if ( cardproperty )
{
SetCardValues(cardproperty, document);
cardproperty.AddCardToDatabase(uri);
}
}
return true; // close the window
}
function EditCardOKButton()
{
SetCardValues(editCard.card, document);
editCard.card.EditCardToDatabase(editCard.abURI);
// callback to allow caller to update
if ( editCard.okCallback )
editCard.okCallback();
return true; // close the window
}
// Move the data from the cardproperty to the dialog
function GetCardValues(cardproperty, doc)
{
if ( cardproperty )
{
doc.getElementById('FirstName').value = cardproperty.FirstName;
doc.getElementById('LastName').value = cardproperty.LastName;
doc.getElementById('DisplayName').value = cardproperty.DisplayName;
doc.getElementById('NickName').value = cardproperty.NickName;
doc.getElementById('PrimaryEmail').value = cardproperty.PrimaryEmail;
doc.getElementById('SecondEmail').value = cardproperty.SecondEmail;
//doc.getElementById('SendPlainText').value = cardproperty.SendPlainText;
doc.getElementById('WorkPhone').value = cardproperty.WorkPhone;
doc.getElementById('HomePhone').value = cardproperty.HomePhone;
doc.getElementById('FaxNumber').value = cardproperty.FaxNumber;
doc.getElementById('PagerNumber').value = cardproperty.PagerNumber;
doc.getElementById('CellularNumber').value = cardproperty.CellularNumber;
doc.getElementById('HomeAddress').value = cardproperty.HomeAddress;
doc.getElementById('HomeAddress2').value = cardproperty.HomeAddress2;
doc.getElementById('HomeCity').value = cardproperty.HomeCity;
doc.getElementById('HomeState').value = cardproperty.HomeState;
doc.getElementById('HomeZipCode').value = cardproperty.HomeZipCode;
doc.getElementById('HomeCountry').value = cardproperty.HomeCountry;
doc.getElementById('JobTitle').value = cardproperty.JobTitle;
doc.getElementById('Department').value = cardproperty.Department;
doc.getElementById('Company').value = cardproperty.Company;
doc.getElementById('WorkAddress').value = cardproperty.WorkAddress;
doc.getElementById('WorkAddress2').value = cardproperty.WorkAddress2;
doc.getElementById('WorkCity').value = cardproperty.WorkCity;
doc.getElementById('WorkState').value = cardproperty.WorkState;
doc.getElementById('WorkZipCode').value = cardproperty.WorkZipCode;
doc.getElementById('WorkCountry').value = cardproperty.WorkCountry;
doc.getElementById('WebPage1').value = cardproperty.WebPage1;
doc.getElementById('Custom1').value = cardproperty.Custom1;
doc.getElementById('Custom2').value = cardproperty.Custom2;
doc.getElementById('Custom3').value = cardproperty.Custom3;
doc.getElementById('Custom4').value = cardproperty.Custom4;
doc.getElementById('Notes').value = cardproperty.Notes;
}
}
// Move the data from the dialog to the cardproperty to be stored in the database
function SetCardValues(cardproperty, doc)
{
if (cardproperty)
{
cardproperty.FirstName = doc.getElementById('FirstName').value;
cardproperty.LastName = doc.getElementById('LastName').value;
cardproperty.DisplayName = doc.getElementById('DisplayName').value;
cardproperty.NickName = doc.getElementById('NickName').value;
cardproperty.PrimaryEmail = doc.getElementById('PrimaryEmail').value;
cardproperty.SecondEmail = doc.getElementById('SecondEmail').value;
//cardproperty.SendPlainText = doc.getElementById('SendPlainText').value;
cardproperty.WorkPhone = doc.getElementById('WorkPhone').value;
cardproperty.HomePhone = doc.getElementById('HomePhone').value;
cardproperty.FaxNumber = doc.getElementById('FaxNumber').value;
cardproperty.PagerNumber = doc.getElementById('PagerNumber').value;
cardproperty.CellularNumber = doc.getElementById('CellularNumber').value;
cardproperty.HomeAddress = doc.getElementById('HomeAddress').value;
cardproperty.HomeAddress2 = doc.getElementById('HomeAddress2').value;
cardproperty.HomeCity = doc.getElementById('HomeCity').value;
cardproperty.HomeState = doc.getElementById('HomeState').value;
cardproperty.HomeZipCode = doc.getElementById('HomeZipCode').value;
cardproperty.HomeCountry = doc.getElementById('HomeCountry').value;
cardproperty.JobTitle = doc.getElementById('JobTitle').value;
cardproperty.Department = doc.getElementById('Department').value;
cardproperty.Company = doc.getElementById('Company').value;
cardproperty.WorkAddress = doc.getElementById('WorkAddress').value;
cardproperty.WorkAddress2 = doc.getElementById('WorkAddress2').value;
cardproperty.WorkCity = doc.getElementById('WorkCity').value;
cardproperty.WorkState = doc.getElementById('WorkState').value;
cardproperty.WorkZipCode = doc.getElementById('WorkZipCode').value;
cardproperty.WorkCountry = doc.getElementById('WorkCountry').value;
cardproperty.WebPage1 = doc.getElementById('WebPage1').value;
cardproperty.Custom1 = doc.getElementById('Custom1').value;
cardproperty.Custom2 = doc.getElementById('Custom2').value;
cardproperty.Custom3 = doc.getElementById('Custom3').value;
cardproperty.Custom4 = doc.getElementById('Custom4').value;
cardproperty.Notes = doc.getElementById('Notes').value;
}
}
function NewCardCancelButton()
{
top.window.close();
}
function EditCardCancelButton()
{
top.window.close();
}
function GenerateDisplayName()
{
if ( editCard.generateDisplayName )
{
var displayName;
var firstNameField = document.getElementById('FirstName');
var lastNameField = document.getElementById('LastName');
var displayNameField = document.getElementById('DisplayName');
/* todo: i18N work todo here */
/* this used to be XP_GetString(MK_ADDR_FIRST_LAST_SEP) */
/* todo: mscott says there was a pref in 4.5 that would */
/* cause GenerateDisplayName() to do nothing. */
/* the i18N people need it. */
/* find the pref and heed it. */
/* trying to be smart about no using the first last sep */
/* if first or last is missing */
/* todo: is this i18N safe? */
var separator = "";
if ( lastNameField.value && firstNameField.value )
{
if ( editCard.displayLastNameFirst )
separator = editCardLastFirstSeparator;
else
separator = editCardFirstLastSeparator;
}
if ( editCard.displayLastNameFirst )
displayName = lastNameField.value + separator + firstNameField.value;
else
displayName = firstNameField.value + separator + lastNameField.value;
displayNameField.value = displayName;
top.window.title = editCard.titlePrefix + displayName;
}
}
function DisplayNameChanged()
{
// turn off generateDisplayName if the user changes the display name
editCard.generateDisplayName = false;
var title = editCard.titlePrefix + document.getElementById('DisplayName').value;
if ( top.window.title != title )
top.window.title = title;
}

View File

@@ -1,293 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abCardOverlay.dtd">
<overlay id="editcardOverlay"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<html:script language="JavaScript" src="chrome://addressbook/content/abCardOverlay.js"/>
<box id="editcard" align="vertical">
<tabcontrol align="vertical" style="margin:5px">
<tabbox align="horizontal">
<tab>&Name.tab;</tab>
<tab>&Address.tab;</tab>
<tab>&Other.tab;</tab>
</tabbox>
<tabpanel align="vertical" flex="100%" style="border:2px groove white">
<!-- ** Name Tab ** -->
<box index="name" align="vertical" flex="100%">
<html:fieldset flex="100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Name.box;</html:div>
</html:legend>
<box align="vertical" style="width:100%">
<box align="horizontal" flex="100%">
<spring flex="100%"/>
<html:label for="FirstName">&FirstName.label;</html:label>
<html:input type="text" id="FirstName" class="CardEdit" onkeyup="top.GenerateDisplayName()" />
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="LastName">&LastName.label;</html:label>
<html:input id="LastName" type="text" class="CardEdit" onkeyup="top.GenerateDisplayName()"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="DisplayName">&DisplayName.label;</html:label>
<html:input id="DisplayName" type="text" class="CardEdit" onkeyup="top.DisplayNameChanged()"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="NickName">&NickName.label;</html:label>
<html:input id="NickName" type="text" class="CardEdit"/>
</box>
</box>
</html:fieldset>
<html:fieldset flex="100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Internet.box;</html:div>
</html:legend>
<box align="vertical" style="width:100%">
<box align="horizontal">
<spring flex="100%"/>
<html:label for="PrimaryEmail">&PrimaryEmail.label;</html:label>
<html:input id="PrimaryEmail" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="SecondEmail">&SecondEmail.label;</html:label>
<html:input id="SecondEmail" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<box class="CardEditWidth">
<html:input id="SendPlainText" type="checkbox"/>
<html:label for="SendPlainText">&SendPlainText.label;</html:label>
</box>
</box>
</box>
</html:fieldset>
<html:fieldset flex="100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Phones.box;</html:div>
</html:legend>
<box align="vertical" style="width:100%">
<box align="horizontal" style="vertical-align:baseline">
<spring flex="100%"/>
<html:label for="WorkPhone" style="vertical-align:baseline">&WorkPhone.label;</html:label>
<html:input id="WorkPhone" type="text" class="CardEdit" style="vertical-align:baseline"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="HomePhone">&HomePhone.label;</html:label>
<html:input id="HomePhone" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="FaxNumber">&FaxNumber.label;</html:label>
<html:input id="FaxNumber" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="PagerNumber">&PagerNumber.label;</html:label>
<html:input id="PagerNumber" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="CellularNumber">&CellularNumber.label;</html:label>
<html:input id="CellularNumber" type="text" class="CardEdit"/>
</box>
</box>
</html:fieldset>
</box>
<!-- ** Address Tab ** -->
<box index="address" align="vertical" flex="100%">
<html:fieldset flex="100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Home.box;</html:div>
</html:legend>
<box align="vertical" style="width:100%">
<box align="horizontal">
<spring flex="100%"/>
<html:label for="HomeAddress">&HomeAddress.label;</html:label>
<html:input type="text" id="HomeAddress" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="HomeAddress2">&HomeAddress2.label;</html:label>
<html:input type="text" id="HomeAddress2" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="HomeCity">&HomeCity.label;</html:label>
<html:input id="HomeCity" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="HomeState">&HomeState.label;</html:label>
<box class="CardEditWidth">
<html:input id="HomeState" type="text" class="CardEdit" style="min-width:1em; width:8em"/>
<spring flex="100%"/>
<html:label for="HomeZipCode">&HomeZipCode.label;</html:label>
<html:input id="HomeZipCode" type="text" class="CardEdit" style="min-width:1em; width:8em"/>
</box>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="HomeCountry">&HomeCountry.label;</html:label>
<html:input id="HomeCountry" type="text" class="CardEdit"/>
</box>
</box>
</html:fieldset>
<html:fieldset style="width:100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Work.box;</html:div>
</html:legend>
<box align="vertical" style="width:100%">
<box align="horizontal">
<spring flex="100%"/>
<html:label for="JobTitle">&JobTitle.label;</html:label>
<html:input type="text" id="JobTitle" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="Department">&Department.label;</html:label>
<html:input type="text" id="Department" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="Company">&Company.label;</html:label>
<html:input type="text" id="Company" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="WorkAddress">&WorkAddress.label;</html:label>
<html:input type="text" id="WorkAddress" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="WorkAddress2">&WorkAddress2.label;</html:label>
<html:input type="text" id="WorkAddress2" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="WorkCity">&WorkCity.label;</html:label>
<html:input id="WorkCity" type="text" class="CardEdit"/>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="WorkState">&WorkState.label;</html:label>
<box class="CardEditWidth">
<html:input id="WorkState" type="text" class="CardEdit" style="min-width:1em; width:8em"/>
<spring flex="100%"/>
<html:label for="WorkZipCode">&WorkZipCode.label;</html:label>
<html:input id="WorkZipCode" type="text" class="CardEdit" style="min-width:1em; width:8em"/>
</box>
</box>
<box align="horizontal">
<spring flex="100%"/>
<html:label for="WorkCountry">&WorkCountry.label;</html:label>
<html:input id="WorkCountry" type="text" class="CardEdit"/>
</box>
</box>
</html:fieldset>
<!--html:fieldset style="width:100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Web.box;</html:div>
</html:legend-->
<box align="vertical" style="width:100%">
<box align="horizontal">
<!--spring flex="100%"/-->
<html:label for="WebPage1">&WebPage1.label;</html:label>
<html:input type="text" id="WebPage1" class="CardEdit" flex="100%"/>
</box>
</box>
<!--/html:fieldset-->
</box>
<!-- ** Other Tab ** -->
<box index="other" align="vertical" flex="100%">
<box align="vertical" style="width:100%">
<box align="horizontal" flex="100%">
<spring flex="100%"/>
<html:label for="Custom1">&Custom1.label;</html:label>
<html:input type="text" id="Custom1" class="CardEdit"/>
</box>
<box align="horizontal" flex="100%">
<spring flex="100%"/>
<html:label for="Custom2">&Custom2.label;</html:label>
<html:input type="text" id="Custom2" class="CardEdit"/>
</box>
<box align="horizontal" flex="100%">
<spring flex="100%"/>
<html:label for="Custom3">&Custom3.label;</html:label>
<html:input type="text" id="Custom3" class="CardEdit"/>
</box>
<box align="horizontal" flex="100%">
<spring flex="100%"/>
<html:label for="Custom4">&Custom4.label;</html:label>
<html:input type="text" id="Custom4" class="CardEdit"/>
</box>
</box>
<html:fieldset style="width:100%">
<html:legend align="left">
<html:div style="font-weight: bold">&Notes.box;</html:div>
</html:legend>
<box align="vertical" style="width:100%">
<html:textarea id="Notes" rows="15"/>
</box>
</html:fieldset>
</box>
</tabpanel>
</tabcontrol>
</box>
</overlay>

View File

@@ -1,231 +0,0 @@
var zWork = "Work: ";
var zHome = "Home: ";
var zFax = "Fax: ";
var zCellular = "Cellular: ";
var zPager = "Pager: ";
var zCustom1 = "Custom 1: ";
var zCustom2 = "Custom 2: ";
var zCustom3 = "Custom 3: ";
var zCustom4 = "Custom 4: ";
var rdf;
var cvData;
function OnLoadCardView()
{
// This should be in an onload for the card view window, but that is not currently working
rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
var doc = document;
/* data for address book, prefixes: "cvb" = card view box
"cvh" = crad view header
"cv" = card view (normal fields) */
cvData = new Object;
// Card View Box
cvData.CardViewBox = doc.getElementById("CardViewBox");
// Title
cvData.CardTitle = doc.getElementById("CardTitle");
// Name section
cvData.cvbName = doc.getElementById("cvbName");
cvData.cvhName = doc.getElementById("cvhName");
cvData.cvNickname = doc.getElementById("cvNickname");
cvData.cvEmail1 = doc.getElementById("cvEmail1");
cvData.cvEmail2 = doc.getElementById("cvEmail2");
// Home section
cvData.cvbHome = doc.getElementById("cvbHome");
cvData.cvhHome = doc.getElementById("cvhHome");
cvData.cvHomeAddress = doc.getElementById("cvHomeAddress");
cvData.cvHomeAddress2 = doc.getElementById("cvHomeAddress2");
cvData.cvHomeCityStZip = doc.getElementById("cvHomeCityStZip");
cvData.cvHomeCountry = doc.getElementById("cvHomeCountry");
// Other section
cvData.cvbOther = doc.getElementById("cvbOther");
cvData.cvhOther = doc.getElementById("cvhOther");
cvData.cvCustom1 = doc.getElementById("cvCustom1");
cvData.cvCustom2 = doc.getElementById("cvCustom2");
cvData.cvCustom3 = doc.getElementById("cvCustom3");
cvData.cvCustom4 = doc.getElementById("cvCustom4");
cvData.cvNotes = doc.getElementById("cvNotes");
// Phone section
cvData.cvbPhone = doc.getElementById("cvbPhone");
cvData.cvhPhone = doc.getElementById("cvhPhone");
cvData.cvPhWork = doc.getElementById("cvPhWork");
cvData.cvPhHome = doc.getElementById("cvPhHome");
cvData.cvPhFax = doc.getElementById("cvPhFax");
cvData.cvPhCellular = doc.getElementById("cvPhCellular");
cvData.cvPhPager = doc.getElementById("cvPhPager");
// Work section
cvData.cvbWork = doc.getElementById("cvbWork");
cvData.cvhWork = doc.getElementById("cvhWork");
cvData.cvJobTitle = doc.getElementById("cvJobTitle");
cvData.cvDepartment = doc.getElementById("cvDepartment");
cvData.cvCompany = doc.getElementById("cvCompany");
cvData.cvWorkAddress = doc.getElementById("cvWorkAddress");
cvData.cvWorkAddress2 = doc.getElementById("cvWorkAddress2");
cvData.cvWorkCityStZip = doc.getElementById("cvWorkCityStZip");
cvData.cvWorkCountry = doc.getElementById("cvWorkCountry");
}
function DisplayCardViewPane(abNode)
{
var uri = abNode.getAttribute('id');
var cardResource = top.rdf.GetResource(uri);
var card = cardResource.QueryInterface(Components.interfaces.nsIAbCard);
// FIX ME - this should use a i18n name routine in JS
var name = card.DisplayName;
if ( card.FirstName.length + card.LastName.length > 0 )
name = card.FirstName + " " + card.LastName;
var nickname;
if ( card.NickName )
nickname = "\"" + card.NickName + "\"";
var data = top.cvData;
var visible;
// set fields in card view pane
cvSetNode(data.CardTitle, "Card for " + card.DisplayName);
// Name section
cvSetNode(data.cvhName, name);
cvSetNode(data.cvNickname, nickname);
cvSetNode(data.cvEmail1, card.PrimaryEmail);
cvSetNode(data.cvEmail2, card.SecondEmail);
// Home section
visible = cvSetNode(data.cvHomeAddress, card.HomeAddress);
visible = cvSetNode(data.cvHomeAddress2, card.HomeAddress2) || visible;
visible = cvSetCityStateZip(data.cvHomeCityStZip, card.HomeCity, card.HomeState, card.HomeZipCode) || visible;
visible = cvSetNode(data.cvHomeCountry, card.HomeCountry) || visible;
cvSetVisible(data.cvhHome, visible);
// Other section
visible = cvSetNodeWithLabel(data.cvCustom1, zCustom1, card.Custom1);
visible = cvSetNodeWithLabel(data.cvCustom2, zCustom2, card.Custom2) || visible;
visible = cvSetNodeWithLabel(data.cvCustom3, zCustom3, card.Custom3) || visible;
visible = cvSetNodeWithLabel(data.cvCustom4, zCustom4, card.Custom4) || visible;
visible = cvSetNode(data.cvNotes, card.Notes) || visible;
cvSetVisible(data.cvhOther, visible);
// Phone section
visible = cvSetNodeWithLabel(data.cvPhWork, zWork, card.WorkPhone);
visible = cvSetNodeWithLabel(data.cvPhHome, zHome, card.HomePhone) || visible;
visible = cvSetNodeWithLabel(data.cvPhFax, zFax, card.FaxNumber) || visible;
visible = cvSetNodeWithLabel(data.cvPhCellular, zCellular, card.CellularNumber) || visible;
visible = cvSetNodeWithLabel(data.cvPhPager, zPager, card.PagerNumber) || visible;
cvSetVisible(data.cvhPhone, visible);
// Work section
visible = cvSetNode(data.cvJobTitle, card.JobTitle);
visible = cvSetNode(data.cvDepartment, card.Department) || visible;
visible = cvSetNode(data.cvCompany, card.Company) || visible;
visible = cvSetNode(data.cvWorkAddress, card.WorkAddress) || visible;
visible = cvSetNode(data.cvWorkAddress2, card.WorkAddress2) || visible;
visible = cvSetCityStateZip(data.cvWorkCityStZip, card.WorkCity, card.WorkState, card.WorkZipCode) || visible;
visible = cvSetNode(data.cvWorkCountry, card.WorkCountry) || visible;
cvSetVisible(data.cvhWork, visible);
// make the card view box visible
cvSetVisible(top.cvData.CardViewBox, true);
}
function ClearCardViewPane()
{
cvSetVisible(top.cvData.CardViewBox, false);
/* can remove this code now that boxes handle display:none
// HACK - we need to be able to set the entire box or div to display:none when bug fixed
var data = top.cvData;
// title
cvSetVisible(data.CardTitle, false);
// Name section
cvSetVisible(data.cvhName, false);
cvSetVisible(data.cvNickname, false);
cvSetVisible(data.cvEmail1, false);
cvSetVisible(data.cvEmail2, false);
// Home section
cvSetVisible(data.cvhHome, false);
cvSetVisible(data.cvHomeAddress, false);
cvSetVisible(data.cvHomeAddress2, false);
cvSetVisible(data.cvHomeCityStZip, false);
cvSetVisible(data.cvHomeCountry, false);
// Other section
cvSetVisible(data.cvhOther, false);
cvSetVisible(data.cvCustom1, false);
cvSetVisible(data.cvCustom2, false);
cvSetVisible(data.cvCustom3, false);
cvSetVisible(data.cvCustom4, false);
cvSetVisible(data.cvNotes, false);
// Phone section
cvSetVisible(data.cvhPhone, false);
cvSetVisible(data.cvPhWork, false);
cvSetVisible(data.cvPhHome, false);
cvSetVisible(data.cvPhFax, false);
cvSetVisible(data.cvPhCellular, false);
cvSetVisible(data.cvPhPager, false);
// Work section
cvSetVisible(data.cvhWork, false);
cvSetVisible(data.cvJobTitle, false);
cvSetVisible(data.cvDepartment, false);
cvSetVisible(data.cvCompany, false);
cvSetVisible(data.cvWorkAddress, false);
cvSetVisible(data.cvWorkAddress2, false);
cvSetVisible(data.cvWorkCityStZip, false);
cvSetVisible(data.cvWorkCountry, false);
*/
}
function cvSetNodeWithLabel(node, label, text)
{
if ( text )
return cvSetNode(node, label + text);
else
{
cvSetVisible(node, false);
return false;
}
}
function cvSetCityStateZip(node, city, state, zip)
{
var text;
if ( city )
{
text = city;
if ( state || zip )
text += ", ";
}
if ( state )
text += state + " ";
if ( zip )
text += zip;
return cvSetNode(node, text);
}
function cvSetNode(node, text)
{
node.childNodes[0].nodeValue = text;
var visible;
if ( text )
visible = true;
else
visible = false;
cvSetVisible(node, visible);
return visible;
}
function cvSetVisible(node, visible)
{
if ( visible )
node.removeAttribute("hide");
else
node.setAttribute("hide", "true");
}

View File

@@ -1,94 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abCardViewOverlay.dtd">
<overlay xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<html:script language="JavaScript" src="chrome://addressbook/content/abCardViewOverlay.js"/>
<box id="CardViewBox"
align="vertical"
flex="100%"
style="overflow:auto; background-color:#dddddd; padding-left:5px; padding-right:5px">
<html:div hide="true" style="font-size:150%; font-weight:bold; border-bottom:2px solid black" id="CardTitle">*</html:div>
<box align="horizontal" flex="100%">
<box align="vertical" flex="100%" style="width:100px">
<box id="cvbName" align="vertical">
<html:div class="CardViewHeading" hide="true" id="cvhName">*</html:div>
<html:div class="CardViewText" hide="true" id="cvNickname">*</html:div>
<html:div class="CardViewText" hide="true" id="cvEmail1">*</html:div>
<html:div class="CardViewText" hide="true" id="cvEmail2">*</html:div>
</box>
<box id="cvbHome" align="vertical">
<html:div class="CardViewHeading" hide="true" id="cvhHome">&home.heading;</html:div>
<html:div class="CardViewText" hide="true" id="cvHomeAddress">*</html:div>
<html:div class="CardViewText" hide="true" id="cvHomeAddress2">*</html:div>
<html:div class="CardViewText" hide="true" id="cvHomeCityStZip">*</html:div>
<html:div class="CardViewText" hide="true" id="cvHomeCountry">*</html:div>
</box>
<box id="cvbOther" align="vertical">
<html:div class="CardViewHeading" hide="true" id="cvhOther">&other.heading;</html:div>
<html:div class="CardViewText" hide="true" id="cvCustom1">*</html:div>
<html:div class="CardViewText" hide="true" id="cvCustom2">*</html:div>
<html:div class="CardViewText" hide="true" id="cvCustom3">*</html:div>
<html:div class="CardViewText" hide="true" id="cvCustom4">*</html:div>
<html:div class="CardViewText" hide="true" id="cvNotes">*</html:div>
</box>
</box>
<spring style="width:20px"/>
<box align="vertical" flex="100%" style="width:100px">
<box id="cvbPhone" align="vertical">
<html:div class="CardViewHeading" hide="true" id="cvhPhone">&phone.heading;</html:div>
<html:div class="CardViewText" hide="true" id="cvPhWork">*</html:div>
<html:div class="CardViewText" hide="true" id="cvPhHome">*</html:div>
<html:div class="CardViewText" hide="true" id="cvPhFax">*</html:div>
<html:div class="CardViewText" hide="true" id="cvPhCellular">*</html:div>
<html:div class="CardViewText" hide="true" id="cvPhPager">*</html:div>
</box>
<box id="cvbWork" align="vertical">
<html:div class="CardViewHeading" hide="true" id="cvhWork">&work.heading;</html:div>
<html:div class="CardViewText" hide="true" id="cvJobTitle">*</html:div>
<html:div class="CardViewText" hide="true" id="cvDepartment">*</html:div>
<html:div class="CardViewText" hide="true" id="cvCompany">*</html:div>
<html:div class="CardViewText" hide="true" id="cvWorkAddress">*</html:div>
<html:div class="CardViewText" hide="true" id="cvWorkAddress2">*</html:div>
<html:div class="CardViewText" hide="true" id="cvWorkCityStZip">*</html:div>
<html:div class="CardViewText" hide="true" id="cvWorkCountry">*</html:div>
</box>
</box>
</box>
</box>
</overlay>

View File

@@ -1,257 +0,0 @@
// functions needed from abMainWindow and abSelectAddresses
// Controller object for Results Pane
var ResultsPaneController =
{
IsCommandEnabled: function(command)
{
dump('ResultsPaneController::IsCommandEnabled(' + command + ')\n');
switch ( command )
{
case "cmd_selectAll":
return true;
case "cmd_delete":
var resultsTree = document.getElementById('resultsTree');
if ( resultsTree && resultsTree.selectedItems )
return true;
else
return false;
default:
return false;
}
},
DoCommand: function(command)
{
var resultsTree = document.getElementById('resultsTree');
switch ( command )
{
case "cmd_selectAll":
if ( resultsTree )
{
dump("select all now!!!!!!" + "\n");
resultsTree.selectAll();
}
break;
case "cmd_delete":
if ( resultsTree )
{
var cardList = resultsTree.selectedItems;
top.addressbook.DeleteCards(resultsTree, resultsTree, cardList);
}
break;
}
}
};
// Controller object for Dir Pane
var DirPaneController =
{
IsCommandEnabled: function(command)
{
dump('DirPaneController::IsCommandEnabled(' + command + ')\n');
switch ( command )
{
case "cmd_selectAll":
return true;
case "cmd_delete":
var dirTree = document.getElementById('dirTree');
if ( dirTree && dirTree.selectedItems )
return true;
else
return false;
default:
return false;
}
},
DoCommand: function(command)
{
var dirTree = document.getElementById('dirTree');
switch ( command )
{
case "cmd_selectAll":
if ( dirTree )
{
dump("select all now!!!!!!" + "\n");
dirTree.selectAll();
}
break;
case "cmd_delete":
if ( dirTree )
top.addressbook.DeleteAddressBooks(dirTree.database, dirTree, dirTree.selectedItems);
break;
}
}
};
function SetupCommandUpdateHandlers()
{
var widget;
// dir pane
widget = document.getElementById('dirTree');
if ( widget )
widget.controller = DirPaneController;
// results pane
widget = document.getElementById('resultsTree');
if ( widget )
widget.controller = ResultsPaneController;
}
function AbNewCard()
{
var selectedAB = 0;
var tree = document.getElementById('dirTree');
if ( tree && tree.selectedItems && (tree.selectedItems.length == 1) )
selectedAB = tree.selectedItems[0].getAttribute('id');
goNewCardDialog(selectedAB);
}
function AbEditCard()
{
var rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
var resultsTree = document.getElementById('resultsTree');
if ( resultsTree.selectedItems && resultsTree.selectedItems.length == 1 )
{
var uri = resultsTree.selectedItems[0].getAttribute('id');
var card = rdf.GetResource(uri);
card = card.QueryInterface(Components.interfaces.nsIAbCard);
goEditCardDialog(document.getElementById('resultsTree').getAttribute('ref'),
card, top.editCardCallback);
}
}
function AbNewMessage()
{
var msgComposeService = Components.classes["component://netscape/messengercompose"].getService();
msgComposeService = msgComposeService.QueryInterface(Components.interfaces.nsIMsgComposeService);
msgComposeService.OpenComposeWindowWithValues(null, 0, GetSelectedAddresses(), null, null,
null, null, null);
}
function GetSelectedAddresses()
{
var item, uri, rdf, cardResource, card;
var selectedAddresses = "";
var resultsTree = document.getElementById('resultsTree');
rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
if ( resultsTree.selectedItems && resultsTree.selectedItems.length )
{
for ( item = 0; item < resultsTree.selectedItems.length; item++ )
{
uri = resultsTree.selectedItems[item].getAttribute('id');
cardResource = rdf.GetResource(uri);
card = cardResource.QueryInterface(Components.interfaces.nsIAbCard);
if ( selectedAddresses )
selectedAddresses += ",";
selectedAddresses += "\"" + card.DisplayName + "\" <" + card.PrimaryEmail + ">";
}
}
dump("selectedAddresses = " + selectedAddresses + "\n");
return selectedAddresses;
}
function SelectFirstAddressBook()
{
var tree = document.getElementById('dirTree');
var body = document.getElementById('dirTreeBody');
if ( tree && body )
{
var treeitems = body.getElementsByTagName('treeitem');
if ( treeitems && treeitems.length > 0 )
{
tree.selectItem(treeitems[0]);
ChangeDirectoryByDOMNode(treeitems[0]);
}
}
}
function DirPaneSelectionChange()
{
// FIX ME - deselect the items in the results pane to work around tree bug
var resultsTree = document.getElementById('resultsTree');
if ( resultsTree )
resultsTree.clearItemSelection();
// ----
var tree = document.getElementById('dirTree');
if ( tree && tree.selectedItems && (tree.selectedItems.length == 1) )
ChangeDirectoryByDOMNode(tree.selectedItems[0]);
else
{
var tree = document.getElementById('resultsTree');
if ( tree )
tree.setAttribute('ref', null);
}
}
function ChangeDirectoryByDOMNode(dirNode)
{
var uri = dirNode.getAttribute('id');
dump("uri = " + uri + "\n");
var tree = document.getElementById('resultsTree');
if ( tree )
tree.setAttribute('ref', uri);
}
function ResultsPaneSelectionChange()
{
// FIX ME! - Should use some js var to determine abmain vs selectaddress dialog
// not in ab window if no parent.parent.rdf
if ( parent.parent.rdf )
{
var tree = document.getElementById('resultsTree');
if ( tree && tree.selectedItems && (tree.selectedItems.length == 1) )
DisplayCardViewPane(tree.selectedItems[0]);
else
ClearCardViewPane();
}
}
function SortResultPane(column, sortKey)
{
var node = document.getElementById(column);
if(!node) return(false);
var isupports = Components.classes["component://netscape/rdf/xul-sort-service"].getService();
if (!isupports) return(false);
var xulSortService = isupports.QueryInterface(Components.interfaces.nsIXULSortService);
if (!xulSortService) return(false);
// sort!!!
sortDirection = "ascending";
var currentDirection = node.getAttribute('sortDirection');
if (currentDirection == "ascending")
sortDirection = "descending";
else if (currentDirection == "descending")
sortDirection = "ascending";
else sortDirection = "ascending";
xulSortService.Sort(node, sortKey, sortDirection);
return(true);
}

View File

@@ -1,64 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abDirTreeOverlay.dtd">
<overlay xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- FIX ME - remove document.commandDispatcher.updateCommands() when tree selection calls this automatically -->
<tree id="dirTree"
class="abDirectory"
style="width:100%; height:100%"
ref="abdirectory://"
open="true"
datasources="rdf:addressdirectory"
onselect="DirPaneSelectionChange(); document.commandDispatcher.updateCommands('select');">
<template>
<rule>
<treechildren>
<treeitem uri="...">
<treerow >
<treecell indent="true" value="rdf:http://home.netscape.com/NC-rdf#DirName"/>
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecol rdf:resource="http://home.netscape.com/NC-rdf#DirName"/>
<treehead>
<treerow>
<treecell>&directoryColumn.label;</treecell>
</treerow>
</treehead>
<treechildren id="dirTreeBody"
rdf:containment="http://home.netscape.com/NC-rdf#child"
rdf:ignore="http://home.netscape.com/NC-rdf#CardChild">
</treechildren>
</tree>
</overlay>

View File

@@ -1,39 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<?xml-stylesheet href="chrome://addressbook/skin/" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abCardOverlay.xul"?>
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="OnLoadEditCard()"
class="dialog"
align="vertical">
<keyset id="keyset"/>
<box id="editcard"/>
<box id="okCancelButtons"/>
</window>

View File

@@ -1,63 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<?xml-stylesheet href="chrome://addressbook/skin/" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abCardOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abNewCardDialog.dtd">
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
title="&editcardWindow.title;"
onload="OnLoadNewCard()"
class="dialog"
align="vertical">
<!--html:script language="JavaScript" src="resource:/res/samples/DumpDOM.js"/-->
<keyset id="keyset"/>
<box align="horizontal">
<html:label for="abPopup">&chooseAddressBook.label;</html:label>
<html:select id="abPopup" ref="abdirectory://" datasources="rdf:addressdirectory">
<template>
<html:option uri="..." value="rdf:http://home.netscape.com/NC-rdf#DirUri">
<text value="rdf:http://home.netscape.com/NC-rdf#DirName"/>
</html:option>
</template>
</html:select>
</box>
<!--box align="horizontal">
<html:label for="chooseAddressBook">&chooseAddressBook.label;</html:label>
<html:select id="chooseAddressBook">
</html:select>
</box-->
<spring style="height:1em"/>
<box id="editcard"/>
<box id="okCancelButtons"/>
</window>

View File

@@ -1,66 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abResultsTreeOverlay.dtd">
<overlay xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- FIX ME - remove document.commandDispatcher.updateCommands() when tree selection calls this automatically -->
<tree id="resultsTree"
class="abResults"
style="width:100%; height:100%"
datasources="rdf:addressdirectory rdf:addresscard"
onselect="top.ResultsPaneSelectionChange(); document.commandDispatcher.updateCommands('select');"
ondblclick="top.AbEditCard()"
containment="http://home.netscape.com/NC-rdf#CardChild">
<template>
<rule>
<treechildren>
<treeitem uri="...">
<treerow >
<treecell indent="true" value="rdf:http://home.netscape.com/NC-rdf#DisplayName"/>
<treecell value="rdf:http://home.netscape.com/NC-rdf#PrimaryEmail"/>
<treecell value="rdf:http://home.netscape.com/NC-rdf#WorkPhone"/>
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecol style="width:20%" id="NameColumn" rdf:resource="http://home.netscape.com/NC-rdf#DisplayName"/>
<treecol style="width:21%" id="EmailColumn" rdf:resource="http://home.netscape.com/NC-rdf#PrimaryEmail"/>
<treecol style="width:20%" id="WorkPhoneColumn" rdf:resource="http://home.netscape.com/NC-rdf#WorkPhone"/>
<treehead>
<treerow>
<treecell onclick="return top.SortResultPane('NameColumn', 'http://home.netscape.com/NC-rdf#DisplayName');">&nameColumn.label;</treecell>
<treecell onclick="return top.SortResultPane('EmailColumn', 'http://home.netscape.com/NC-rdf#PrimaryEmail');">&emailColumn.label;</treecell>
<treecell onclick="return top.SortResultPane('WorkPhoneColumn', 'http://home.netscape.com/NC-rdf#WorkPhone');">&phoneColumn.label;</treecell>
</treerow>
</treehead>
</tree>
</overlay>

View File

@@ -1,183 +0,0 @@
var addressbook = 0;
var composeWindow = 0;
var msgCompFields = 0;
var editCardCallback = 0;
// localization strings
var prefixTo = "To: ";
var prefixCc = "Cc: ";
var prefixBcc = "Bcc: ";
function OnLoadSelectAddress()
{
var toAddress="", ccAddress="", bccAddress="";
doSetOKCancel(SelectAddressOKButton, 0);
top.addressbook = Components.classes["component://netscape/addressbook"].createInstance();
top.addressbook = top.addressbook.QueryInterface(Components.interfaces.nsIAddressBook);
// look in arguments[0] for parameters
if (window.arguments && window.arguments[0])
{
// keep parameters in global for later
if ( window.arguments[0].composeWindow )
top.composeWindow = window.arguments[0].composeWindow;
if ( window.arguments[0].msgCompFields )
top.msgCompFields = window.arguments[0].msgCompFields;
if ( window.arguments[0].toAddress )
toAddress = window.arguments[0].toAddress;
if ( window.arguments[0].ccAddress )
ccAddress = window.arguments[0].ccAddress;
if ( window.arguments[0].bccAddress )
bccAddress = window.arguments[0].bccAddress;
dump("onload top.composeWindow: " + top.composeWindow + "\n");
dump("onload toAddress: " + toAddress + "\n");
// put the addresses into the bucket
AddAddressFromComposeWindow(toAddress, prefixTo);
AddAddressFromComposeWindow(ccAddress, prefixCc);
AddAddressFromComposeWindow(bccAddress, prefixBcc);
}
SelectFirstAddressBook();
}
function AddAddressFromComposeWindow(addresses, prefix)
{
if ( addresses )
{
var addressArray = addresses.split(",");
for ( var index = 0; index < addressArray.length; index++ )
{
// remove leading spaces
while ( addressArray[index][0] == " " )
addressArray[index] = addressArray[index].substring(1, addressArray[index].length);
AddAddressIntoBucket(prefix + addressArray[index]);
}
}
}
function SelectAddressOKButton()
{
var body = document.getElementById('bucketBody');
var item, row, cell, text, colon;
var toAddress="", ccAddress="", bccAddress="";
for ( var index = 0; index < body.childNodes.length; index++ )
{
item = body.childNodes[index];
if ( item.childNodes && item.childNodes.length )
{
row = item.childNodes[0];
if ( row.childNodes && row.childNodes.length )
{
cell = row.childNodes[0];
if ( cell.childNodes && cell.childNodes.length )
{
text = cell.childNodes[0];
if ( text && text.data && text.data.length )
{
switch ( text.data[0] )
{
case prefixTo[0]:
if ( toAddress )
toAddress += ", ";
toAddress += text.data.substring(prefixTo.length, text.data.length);
break;
case prefixCc[0]:
if ( ccAddress )
ccAddress += ", ";
ccAddress += text.data.substring(prefixCc.length, text.data.length);
break;
case prefixBcc[0]:
if ( bccAddress )
bccAddress += ", ";
bccAddress += text.data.substring(prefixBcc.length, text.data.length);
break;
}
}
}
}
}
}
// reset the UI in compose window
msgCompFields.SetTo(toAddress);
msgCompFields.SetCc(ccAddress);
msgCompFields.SetBcc(bccAddress);
top.composeWindow.CompFields2Recipients(top.msgCompFields);
return true;
}
function SelectAddressToButton()
{
AddSelectedAddressesIntoBucket(prefixTo);
}
function SelectAddressCcButton()
{
AddSelectedAddressesIntoBucket(prefixCc);
}
function SelectAddressBccButton()
{
AddSelectedAddressesIntoBucket(prefixBcc);
}
function AddSelectedAddressesIntoBucket(prefix)
{
var item, uri, rdf, cardResource, card, address;
rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
var resultsTree = document.getElementById('resultsTree');
if ( resultsTree && resultsTree.selectedItems && resultsTree.selectedItems.length )
{
for ( item = 0; item < resultsTree.selectedItems.length; item++ )
{
uri = resultsTree.selectedItems[item].getAttribute('id');
cardResource = rdf.GetResource(uri);
card = cardResource.QueryInterface(Components.interfaces.nsIAbCard);
address = prefix + "\"" + card.DisplayName + "\" <" + card.PrimaryEmail + ">";
AddAddressIntoBucket(address);
}
}
}
function AddAddressIntoBucket(address)
{
var body = document.getElementById("bucketBody");
var item = document.createElement('treeitem');
var row = document.createElement('treerow');
var cell = document.createElement('treecell');
var text = document.createTextNode(address);
cell.appendChild(text);
row.appendChild(cell);
item.appendChild(row);
body.appendChild(item);
}
function RemoveSelectedFromBucket()
{
var bucketTree = document.getElementById("addressBucket");
if ( bucketTree )
{
var body = document.getElementById("bucketBody");
if ( body && bucketTree.selectedItems && bucketTree.selectedItems.length )
{
for ( var item = bucketTree.selectedItems.length - 1; item >= 0; item-- )
body.removeChild(bucketTree.selectedItems[item]);
}
}
}

View File

@@ -1,141 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<?xml-stylesheet href="chrome://addressbook/skin/" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abDirTreeOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abResultsTreeOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abSelectAddressesDialog.dtd">
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&selectAddressWindow.title;"
class="dialog"
width="640" height="480"
style="width:100%; height:100%; padding:0px"
onload="OnLoadSelectAddress()"
align="vertical">
<html:script language="JavaScript" src="chrome://addressbook/content/abCommon.js"/>
<html:script language="JavaScript" src="chrome://addressbook/content/abSelectAddressesDialog.js"/>
<html:script language="JavaScript" src="chrome://messengercompose/content/MsgComposeCommands.js"/>
<html:script language="JavaScript" src="chrome://global/content/globalOverlay.js"/>
<!--html:script language="JavaScript" src="resource:/res/samples/DumpDOM.js"/-->
<keyset id="keyset"/>
<!-- Thin box across top, show names containing & stop, search buttons -->
<box align="horizontal" style="width:100%; padding:0px; padding-top:2px; padding-bottom:2px">
<html:div flex="100%" style="vertical-align: middle;">
<html:label for="searchtext" tabindex="0">&search.label;</html:label>
<html:input type="text" id="searchtext" flex="100%"/>
</html:div>
<spring style="width: 1em;"/>
<titledbutton id="stop" value="&stopButton.label;" class="push" onclick="SelectAddressStopButton()"/>
<spring style="width:5px"/>
<titledbutton id="search" value="&searchButton.label;" class="push" onclick="SelectAddressSearchButton()"/>
</box>
<!-- Main box, 3 pane and majority of buttons -->
<box align="horizontal" flex="100%">
<!-- 3 Pane box -->
<box align="horizontal" flex="100%" style="border-top:solid black 1px; border-bottom:solid black 1px">
<!-- dir tree -->
<box align="horizontal"
style="width:200px; height:100%; background-color:white; border-right:solid black 1px">
<!-- FIX ME - div is hack to make tree scroll properly -->
<html:div style="width:100px;height:100px" flex="1">
<tree id="dirTree"/>
</html:div>
</box>
<splitter collapse="before"/>
<!-- Box that holds results pane, (to,cc,bcc buttons), and address bucket -->
<box align="vertical" flex="100%" style="border-left:solid black 1px; border-right:solid black 1px">
<!-- Box that holds results pane and (to,cc,bcc buttons) -->
<box align="vertical" flex="100%">
<!-- results tree -->
<box flex="100%" align="vertical"
style="background-color:white; border-bottom:solid black 1px">
<!-- FIX ME - div is hack to make tree scroll properly -->
<html:div style="width:100px;height:100px" flex="1">
<tree id="resultsTree"/>
</html:div>
</box>
<!-- Box that holds (to,cc,bcc buttons) -->
<box align="horizontal" style="padding:0.3em; border-bottom:solid black 1px">
<spring flex="50%"/>
<titledbutton id="toButton" value="&toButton.label;" class="push" onclick="SelectAddressToButton()"/>
<spring style="width:10px"/>
<titledbutton id="ccButton" value="&ccButton.label;" class="push" onclick="SelectAddressCcButton()"/>
<spring style="width:10px"/>
<titledbutton id="bccButton" value="&bccButton.label;" class="push" onclick="SelectAddressBccButton()"/>
<spring flex="50%"/>
</box>
</box>
<splitter collapse="after"/>
<!-- Address bucket -->
<box align="vertical" style="height:170px; background-color:white; border-top:solid black 1px">
<html:div style="width:100px;height:100px" flex="1">
<tree id="addressBucket" style="width:100%; height:100%">
<treecol style="width:100%"/>
<treechildren id="bucketBody"/>
</tree>
</html:div>
</box>
</box>
</box>
<!-- Box with buttons on right edge of window -->
<box align="vertical" style="padding: .5em; padding-right: 0px">
<box align="vertical" flex="50%">
<spring style="height:10px"/>
<titledbutton id="new" value="&newButton.label;" class="push" onclick="AbNewCard()"/>
<spring style="height:10px"/>
<titledbutton id="edit" value="&editButton.label;" class="push" onclick="AbEditCard()"/>
<spring style="height:10px"/>
<titledbutton id="view" value="&viewButton.label;" class="push" onclick="SelectAddressViewButton()"/>
<spring flex="100%"/>
</box>
<box align="vertical" flex="50%">
<spring flex="50%"/>
<titledbutton id="remove" value="&removeButton.label;" class="push" onclick="RemoveSelectedFromBucket()"/>
<spring flex="50%"/>
</box>
</box>
</box>
<!-- OK & Cancel buttons -->
<box id="okCancelButtons"/>
</window>

View File

@@ -1,183 +0,0 @@
var addressbook = 0;
var editCardCallback = 0;
// functions used only by addressbook
function OnLoadAddressBook()
{
// FIX ME - later we will be able to use onload from the overlay
OnLoadCardView();
top.addressbook = Components.classes["component://netscape/addressbook"].createInstance();
top.addressbook = top.addressbook.QueryInterface(Components.interfaces.nsIAddressBook);
top.editCardCallback = UpdateCardView;
try {
top.addressbook.SetWebShellWindow(window)
}
catch (ex) {
dump("failed to set webshell window\n");
}
SetupCommandUpdateHandlers();
SelectFirstAddressBook();
}
function CommandUpdate_AddressBook()
{
dump("CommandUpdate_AddressBook\n");
// get selection info from dir pane
var tree = document.getElementById('dirTree');
var oneAddressBookSelected = false;
if ( tree && tree.selectedItems && (tree.selectedItems.length == 1) )
oneAddressBookSelected = true;
dump("oneAddressBookSelected = " + oneAddressBookSelected + "\n");
// get selection info from results pane
var selectedCards = GetSelectedAddresses();
var oneOrMoreCardsSelected = false;
if ( selectedCards )
oneOrMoreCardsSelected = true;
// set commands to enabled / disabled
goSetCommandEnabled('cmd_PrintCard', oneOrMoreCardsSelected);
goSetCommandEnabled('cmd_SortByName', oneAddressBookSelected);
goSetCommandEnabled('cmd_SortByEmail', oneAddressBookSelected);
goSetCommandEnabled('cmd_SortByPhone', oneAddressBookSelected);
AbUpdateCommandDelete();
}
// This function updates the text of the delete menu item and sets the state of the delete button
function AbUpdateCommandDelete()
{
var command = "cmd_delete";
var focusedElement = document.commandDispatcher.focusedElement;
var id = 0;
if ( focusedElement )
id = focusedElement.getAttribute('id');
dump("focusedOn = " + id + "\n");
switch ( id )
{
case "dirTree":
// menu text
goSetMenuValue(command, 'valueAddressBook');
// delete button
var dirTree = document.getElementById('dirTree');
var numSelected = 0;
if ( dirTree && dirTree.selectedItems )
numSelected = dirTree.selectedItems.length;
goSetCommandEnabled('button_delete', (numSelected>0));
break;
case "resultsTree":
// menu text
var resultsTree = document.getElementById('resultsTree');
var numSelected = 0;
if ( resultsTree && resultsTree.selectedItems )
numSelected = resultsTree.selectedItems.length;
if ( numSelected < 2 )
goSetMenuValue(command, 'valueCard');
else
goSetMenuValue(command, 'valueCards');
// delete button
goSetCommandEnabled('button_delete', (numSelected>0));
break;
default:
goSetMenuValue(command, 'valueDefault');
goSetCommandEnabled('button_delete', false);
break;
}
}
function UpdateCardView()
{
var tree = document.getElementById('resultsTree');
if ( tree && tree.selectedItems && (tree.selectedItems.length == 1) )
DisplayCardViewPane(tree.selectedItems[0]);
}
function AbClose()
{
top.window.close();
}
function AbNewAddressBook()
{
var dialog = window.openDialog("chrome://addressbook/content/abAddressBookNameDialog.xul",
"",
"chrome",
{title:"New Address Book",
okCallback:AbCreateNewAddressBook});
}
function AbCreateNewAddressBook(name)
{
top.addressbook.NewAddressBook(document.getElementById('dirTree').database, document.getElementById('resultsTree'), name);
}
function AbPrintCard()
{
dump("print card\n");
try {
addressbook.PrintCard();
}
catch (ex) {
dump("failed to print card\n");
}
}
function AbPrintAddressBook()
{
dump("print address book \n");
try {
addressbook.PrintAddressbook();
}
catch (ex) {
dump("failed to print address book\n");
}
}
function AbImport()
{
addressbook.ImportAddressBook();
}
/*
function AbDelete()
{
// dump("\AbDelete from XUL\n");
var tree = document.getElementById('resultsTree');
if ( tree )
{
//get the selected elements
var cardList = tree.selectedItems;
//get the current folder
var srcDirectory = document.getElementById('resultsTree');
dump("srcDirectory = " + srcDirectory + "\n");
top.addressbook.DeleteCards(tree, srcDirectory, cardList);
}
}
*/
/*
function AbDeleteDirectory()
{
// dump("\AbDeleteDirectory from XUL\n");
var tree = document.getElementById('dirTree');
// if ( tree && tree.selectedItems && tree.selectedItems.length )
if ( tree )
top.addressbook.DeleteAddressBooks(tree.database, tree, tree.selectedItems);
}
*/

View File

@@ -1,247 +0,0 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<?xml-stylesheet href="chrome://addressbook/skin/" type="text/css"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://global/content/tasksOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abDirTreeOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abResultsTreeOverlay.xul"?>
<?xul-overlay href="chrome://addressbook/content/abCardViewOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://addressbook/locale/abMainWindow.dtd">
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
height="420"
width="600"
align="vertical"
title="&addressbookWindow.title;"
windowtype="mail:addressbook"
onload="OnLoadAddressBook()">
<html:script language="JavaScript" src="chrome://addressbook/content/addressbook.js"/>
<html:script language="JavaScript" src="chrome://addressbook/content/abCommon.js"/>
<!--html:script language="JavaScript" src="resource:/res/samples/DumpDOM.js"/-->
<commands id="commands">
<commandset id="CommandUpdate_AddressBook"
commandupdater="true"
events="focus,blur,select"
oncommandupdate="CommandUpdate_AddressBook()"/>
<commandset id="globalEditMenuItems"/>
</commands>
<broadcasterset id="broadcasterset">
<!-- File Menu -->
<broadcaster id="cmd_newNavigator"/>
<broadcaster id="cmd_newMessage"/>
<broadcaster id="cmd_PrintCard" oncommand="AbPrintCard()" disabled="true"/>
<broadcaster id="cmd_close" oncommand="AbClose()"/>
<broadcaster id="cmd_quit"/>
<!-- Edit Menu -->
<broadcaster id="cmd_undo"/>
<broadcaster id="cmd_redo"/>
<broadcaster id="cmd_cut"/>
<broadcaster id="cmd_copy"/>
<broadcaster id="cmd_paste"/>
<broadcaster id="cmd_delete"
valueAddressBook="&deleteAbCmd.label;"
valueCard="&deleteCardCmd.label;"
valueCards="&deleteCardsCmd.label;"/>
<broadcaster id='cmd_selectAll'/>
<broadcaster id="cmd_preferences"/>
</broadcasterset>
<keyset id="keyset">
<!-- File Menu -->
<key id="key_newNavigator"/>
<key id="key_newMessage"/>
<key id="key_PrintCard" command="true" key="&printCardViewCmd.key;" observes="cmd_PrintCard" />
<key id="key_close"/>
<key id="key_quit"/>
<!-- Edit Menu -->
<key id="key_undo"/>
<key id="key_redo"/>
<key id="key_cut"/>
<key id="key_copy"/>
<key id="key_paste"/>
<key id="key_delete"/>
<key id="key_selectAll"/>
<key id="key_preferences"/>
</keyset>
<toolbox>
<menubar>
<menu id="menu_File">
<menupopup id="menu_FilePopup">
<menuitem value="&newCard.label;" accesskey="&newCard.accesskey;" oncommand="AbNewCard()"/>
<menu id="menu_New">
<menupopup>
<menuitem value="&newListCmd.label;" accesskey="&newListCmd.accesskey;" oncommand="AbNewList()"/>
<menuitem value="&newAddressBookCmd.label;" accesskey="&newAddressBookCmd.accesskey;" oncommand="AbNewAddressBook()"/>
<menuitem value="&newDirectoryCmd.label;" accesskey="&newDirectoryCmd.accesskey;" oncommand="AbNewDirectoryt()"/>
<menuseparator/>
<menuitem id="menu_newNavigator"/>
<menuitem id="menu_newMessage"/>
<menuitem id="cmd_newCard"/>
</menupopup>
</menu>
<menuseparator/>
<menuitem id="menu_close"/>
<menuseparator/>
<menuitem value="&importCmd.label;" oncommand="AbImport()"/>
<menuitem value="&exportCmd.label;" oncommand="AbExport()"/>
<menuseparator/>
<menuitem id="menu_pageSetup"/>
<menuitem value="&printPreviewCmd.label;" oncommand="AbPrintPreview()"/>
<menuitem value="&printCardViewCmd.label;" key="key_PrintCard" observes="cmd_PrintCard"/>
<menuitem value="&printAddressBook.label;" oncommand="AbPrintAddressBook()"/>
<menuseparator/>
</menupopup>
</menu>
<menu id="menu_Edit">
<menupopup>
<menuitem id="menu_undo"/>
<menuitem id="menu_redo"/>
<menuseparator/>
<menuitem id="menu_cut"/>
<menuitem id="menu_copy"/>
<menuitem id="menu_paste"/>
<menuitem id="menu_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"/>
<menuseparator/>
<menuitem value="&editCardCmd.label;"
accesskey="&editCardCmd.accesskey;"
oncommand="AbEditCard();"/>
<menuitem value="&htmlDomainCmd.label;"
accesskey="&htmlDomainCmd.accesskey;"
oncommand="AbHTMLDomain();"/>
<menuseparator/>
<menuitem id="menu_preferences" oncommand="goPreferences('addressbook.xul', 'chrome://addressbook/content/pref-addressing.xul')"/>
</menupopup>
</menu>
<menu id="menu_View">
<menupopup>
<menu id="menu_Toolbars">
<menupopup>
<menuitem id="menu_showAbToolbar"
value="&showAbToolbarCmd.label;"
accesskey="&showAbToolbarCmd.accesskey;"
oncommand="goToggleToolbar('abToolbar', 'menu_showAbToolbar')"
checked="true"/>
<menuitem id="menu_showTaskbar"/>
</menupopup>
</menu>
<menuitem value="&showCardPane.label;" oncommand="AbShowCardPane()"/>
<menu value="&sortMenu.label;">
<menupopup>
<menuitem value="&sortByNameCmd.label;"
id="cmd_SortByName"
disabled="true"
oncommand="top.SortResultPane('NameColumn', 'http://home.netscape.com/NC-rdf#DisplayName')"/>
<menuitem value="&sortByEmailCmd.label;"
id="cmd_SortByEmail"
disabled="true"
oncommand="top.SortResultPane('EmailColumn', 'http://home.netscape.com/NC-rdf#PrimaryEmail')"/>
<menuitem value="&sortByOrganizationCmd.label;" oncommand="AbSortByOrganization()"/>
<menuitem value="&sortByNicknameCmd.label;" oncommand="AbSortByNickname()"/>
<menuitem value="&sortByPhoneCmd.label;"
id="cmd_SortByPhone"
disabled="true"
oncommand="top.SortResultPane('WorkPhoneColumn', 'http://home.netscape.com/NC-rdf#WorkPhone')"/>
<menuitem value="&sortByCityCmd.label;" oncommand="AbSortByCity()"/>
<menuseparator/>
<menuitem value="&sortAscendingCmd.label;" oncommand="AbSortAscending()"/>
<menuitem value="&sortDescendingCmd.label;" oncommand="AbSortDescending()"/>
</menupopup>
</menu>
</menupopup>
</menu>
<menu id="tasksMenu"/>
<menu id="menu_Help"/>
<spring flex="100%"/>
</menubar>
<toolbar id="abToolbar" persist="collapsed">
<titledbutton src="&newcardButton.img;" align="top" value="&newcardButton.label;" onclick="AbNewCard()"/>
<titledbutton src="&newlistButton.img;" align="top" value="&newlistButton.label;" onclick="AbNewList()"/>
<titledbutton src="&editButton.img;" align="top" value="&editButton.label;" onclick="AbEditCard()"/>
<titledbutton src="&newmsgButton.img;" align="top" value="&newmsgButton.label;" onclick="AbNewMessage()"/>
<titledbutton id="button_delete" disabled="true" src="&deleteButton.img;" align="top" value="&deleteButton.label;" onclick="AbDelete()"/>
<html:div class="separator" align="vertical"/>
<box align="vertical">
<spring flex="100%"/>
<html:div style="padding-left:5px; padding-bottom:2px">&showNames.label;</html:div>
<html:input id="searchtext" type="text" align="bottom" style="min-width:100px; min-height:25px; padding-bottom:0px"/>
</box>
<titledbutton src="&stopButton.img;" align="top" value="&stopButton.label;" onclick="AbStop()"/>
<titledbutton src="&searchButton.img;" align="top" value="&searchButton.label;" onclick="AbSearch()"/>
<spring flex="100%"/>
<titledbutton id="Throbber" align="right" onclick="MsgHome('http://www.mozilla.org/')"/>
</toolbar>
</toolbox>
<!-- The main address book three pane -->
<box align="horizontal" flex="100%">
<!-- dir tree -->
<box align="horizontal"
style="width:200px; height:100%; background-color:white; border-right:solid black 1px">
<!-- FIX ME - div is hack to make tree scroll properly -->
<html:div style="width:100px;height:100px" flex="1">
<tree id="dirTree"/>
</html:div>
</box>
<splitter collapse="before"/>
<box align="vertical" flex="100%" style="border-left:solid black 1px">
<!-- results tree -->
<box flex="50%" align="vertical"
style="background-color:white; border-bottom:solid black 1px">
<!-- FIX ME - div is hack to make tree scroll properly -->
<html:div style="width:100px;height:100px" flex="1">
<tree id="resultsTree"/>
</html:div>
</box>
<splitter collapse="after"/>
<!-- card view -->
<box style="height:170px; border-top:solid black 1px">
<box id="CardViewBox"/>
</box>
</box>
</box>
<toolbox id="taskbox"/>
</window>

View File

@@ -1,58 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..
include <$(DEPTH)\config\rules.mak>
install::
$(MAKE_INSTALL) abAddressBookNameDialog.js $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abAddressBookNameDialog.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abCardOverlay.js $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abCardOverlay.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abCardViewOverlay.js $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abCardViewOverlay.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abCommon.js $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abDirTreeOverlay.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abEditCardDialog.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abNewCardDialog.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abResultsTreeOverlay.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abSelectAddressesDialog.js $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) abSelectAddressesDialog.xul $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) addressbook.js $(DIST)\bin\chrome\addressbook\content\default
$(MAKE_INSTALL) addressbook.xul $(DIST)\bin\chrome\addressbook\content\default
clobber::
rm -f $(DIST)\chrome\addressbook\content\default\abAddressBookNameDialog.js
rm -f $(DIST)\chrome\addressbook\content\default\abAddressBookNameDialog.xul
rm -f $(DIST)\chrome\addressbook\content\default\abCardOverlay.js
rm -f $(DIST)\chrome\addressbook\content\default\abCardOverlay.xul
rm -f $(DIST)\chrome\addressbook\content\default\abCardViewOverlay.js
rm -f $(DIST)\chrome\addressbook\content\default\abCardViewOverlay.xul
rm -f $(DIST)\chrome\addressbook\content\default\abCommon.js
rm -f $(DIST)\chrome\addressbook\content\default\abDirTreeOverlay.xul
rm -f $(DIST)\chrome\addressbook\content\default\abEditCardDialog.xul
rm -f $(DIST)\chrome\addressbook\content\default\abNewCardDialog.xul
rm -f $(DIST)\chrome\addressbook\content\default\abResultsTreeOverlay.xul
rm -f $(DIST)\chrome\addressbook\content\default\abSelectAddressesDialog.js
rm -f $(DIST)\chrome\addressbook\content\default\abSelectAddressesDialog.xul
rm -f $(DIST)\chrome\addressbook\content\default\addressbook.js
rm -f $(DIST)\chrome\addressbook\content\default\addressbook.xul

View File

@@ -1,28 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = en-US
include $(topsrcdir)/config/rules.mk

View File

@@ -1,8 +0,0 @@
abAddressBookNameDialog.dtd
abCardOverlay.dtd
abCardViewOverlay.dtd
abDirTreeOverlay.dtd
abMainWindow.dtd
abNewCardDialog.dtd
abResultsTreeOverlay.dtd
abSelectAddressesDialog.dtd

View File

@@ -1,40 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXPORT_RESOURCE_CONTENT = \
$(srcdir)/abAddressBookNameDialog.dtd \
$(srcdir)/abCardOverlay.dtd \
$(srcdir)/abCardViewOverlay.dtd \
$(srcdir)/abDirTreeOverlay.dtd \
$(srcdir)/abMainWindow.dtd \
$(srcdir)/abNewCardDialog.dtd \
$(srcdir)/abResultsTreeOverlay.dtd \
$(srcdir)/abSelectAddressesDialog.dtd \
$(NULL)
include $(topsrcdir)/config/rules.mk
install::
$(INSTALL) $(EXPORT_RESOURCE_CONTENT) $(DIST)/bin/chrome/addressbook/locale/en-US

View File

@@ -1,22 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Labels -->
<!ENTITY name.label "Address Book Name">

View File

@@ -1,65 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Labels -->
<!ENTITY Name.tab "Name">
<!ENTITY Name.box "Name">
<!ENTITY FirstName.label "First:">
<!ENTITY LastName.label "Last:">
<!ENTITY DisplayName.label "Display:">
<!ENTITY NickName.label "Nickname:">
<!ENTITY Internet.box "Internet">
<!ENTITY PrimaryEmail.label "* Email:">
<!ENTITY SecondEmail.label "Additional Email:">
<!ENTITY SendPlainText.label "Send email as plain text (no html)">
<!ENTITY Phones.box "Phones">
<!ENTITY WorkPhone.label "Work:">
<!ENTITY HomePhone.label "Home:">
<!ENTITY FaxNumber.label "Fax:">
<!ENTITY PagerNumber.label "Pager:">
<!ENTITY CellularNumber.label "Cellular:">
<!ENTITY Address.tab "Address">
<!ENTITY Home.box "Home">
<!ENTITY HomeAddress.label "Address:">
<!ENTITY HomeAddress2.label "">
<!ENTITY HomeCity.label "City:">
<!ENTITY HomeState.label "State:">
<!ENTITY HomeZipCode.label "Zip:">
<!ENTITY HomeCountry.label "Country:">
<!ENTITY Work.box "Work">
<!ENTITY JobTitle.label "Title:">
<!ENTITY Department.label "Department:">
<!ENTITY Company.label "Organization:">
<!ENTITY WorkAddress.label "Address:">
<!ENTITY WorkAddress2.label "">
<!ENTITY WorkCity.label "City:">
<!ENTITY WorkState.label "State:">
<!ENTITY WorkZipCode.label "Zip:">
<!ENTITY WorkCountry.label "Country:">
<!--ENTITY Web.box "Web"-->
<!ENTITY WebPage1.label "Web Page:">
<!ENTITY Other.tab "Other">
<!ENTITY Custom1.label "Custom 1:">
<!ENTITY Custom2.label "Custom 2:">
<!ENTITY Custom3.label "Custom 3:">
<!ENTITY Custom4.label "Custom 4:">
<!ENTITY Notes.box "Notes">

View File

@@ -1,25 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Box Headings -->
<!ENTITY home.heading "Home">
<!ENTITY other.heading "Other">
<!ENTITY phone.heading "Phone">
<!ENTITY work.heading "Work">

View File

@@ -1,22 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Column Heading -->
<!ENTITY directoryColumn.label "Directory">

View File

@@ -1,83 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Title -->
<!ENTITY addressbookWindow.title "Address Book">
<!-- Menus: the . means that the menu item isn't implemented yet -->
<!-- File Menu -->
<!ENTITY newCard.label "New Address Book Card">
<!ENTITY newCard.accesskey "n">
<!ENTITY newListCmd.label ".Mailing List">
<!ENTITY newListCmd.accesskey "l">
<!ENTITY newAddressBookCmd.label "Address Book">
<!ENTITY newAddressBookCmd.accesskey "b">
<!ENTITY newDirectoryCmd.label ".Directory">
<!ENTITY newDirectoryCmd.accesskey "d">
<!ENTITY importCmd.label "Import...">
<!ENTITY exportCmd.label ".Export...">
<!ENTITY printPreviewCmd.label ".Print Preview">
<!ENTITY printCardViewCmd.label ".Print Card View...">
<!ENTITY printCardViewCmd.key "P">
<!ENTITY printAddressBook.label ".Print Address Book...">
<!-- Edit Menu -->
<!ENTITY deleteAbCmd.label "Delete Address Book">
<!ENTITY deleteCardCmd.label "Delete Card">
<!ENTITY deleteCardsCmd.label "Delete Selected Cards">
<!ENTITY editCardCmd.label "Edit Card...">
<!ENTITY editCardCmd.accesskey "e">
<!ENTITY htmlDomainCmd.label ".HTML Domains...">
<!ENTITY htmlDomainCmd.accesskey "h">
<!-- View Menu -->
<!ENTITY showAbToolbarCmd.label "Show Address Book Toolbar">
<!ENTITY showAbToolbarCmd.accesskey "a">
<!ENTITY showCardPane.label ".Card Pane">
<!ENTITY sortMenu.label "Sort">
<!ENTITY sortByNameCmd.label "by Name">
<!ENTITY sortByEmailCmd.label "by Email">
<!ENTITY sortByOrganizationCmd.label ".by Organization">
<!ENTITY sortByNicknameCmd.label ".by Nickname">
<!ENTITY sortByPhoneCmd.label "by Phone Number">
<!ENTITY sortByCityCmd.label ".by City">
<!ENTITY sortAscendingCmd.label ".Ascending">
<!ENTITY sortDescendingCmd.label ".Descending">
<!ENTITY stopSearchingCmd.label ".Stop Searching">
<!-- Toolbar items -->
<!ENTITY newcardButton.img "chrome://addressbook/skin/newcard.gif">
<!ENTITY newcardButton.label "New Card">
<!ENTITY newlistButton.img "chrome://addressbook/skin/newlist.gif">
<!ENTITY newlistButton.label ".New List">
<!ENTITY editButton.img "chrome://addressbook/skin/property.gif">
<!ENTITY editButton.label "Edit">
<!ENTITY newmsgButton.img "chrome://addressbook/skin/abnewmsg.gif">
<!ENTITY newmsgButton.label "New Msg">
<!ENTITY deleteButton.img "chrome://messenger/skin/trash.gif">
<!ENTITY deleteButton.label "Delete">
<!ENTITY stopButton.img "resource:/res/toolbar/TB_Stop.gif">
<!ENTITY stopButton.label ".Stop">
<!ENTITY searchButton.img "resource:/res/toolbar/TB_Search.gif">
<!ENTITY searchButton.label ".Search">
<!ENTITY showNames.label "Show names containing:">
<!ENTITY throbber.img "resource:/res/throbber/anims00.gif">
<!ENTITY throbber.url "http://www.mozilla.org/">

View File

@@ -1,24 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Title -->
<!ENTITY editcardWindow.title "New Card">
<!-- Labels -->
<!ENTITY chooseAddressBook.label "Add to: ">

View File

@@ -1,25 +0,0 @@
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
-->
<!-- Column Headings -->
<!ENTITY nameColumn.label "Name">
<!ENTITY emailColumn.label "Email">
<!-- LOCALIZATION NOTE (phoneColumn.label): "#" means "number" -->
<!ENTITY phoneColumn.label "Phone#">

Some files were not shown because too many files have changed in this diff Show More