Fix issues with compiling V8 with LLVM Clang
Added this-> in some places where accessing a method on a templated base class. Added #include <strings.h> for bit_cast, moved it to utils.h and renamed it to BitCast. Patch by Evan Martin <evan@chromium.org>, see http://codereview.chromium.org/894001 and http://codereview.chromium.org/888003 Review URL: http://codereview.chromium.org/888005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4111 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
44d0112b71
commit
16bfc31317
@ -280,9 +280,9 @@ void MacroAssembler::RecordWrite(Register object, Register offset,
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors.
|
||||
if (FLAG_debug_code) {
|
||||
mov(object, Operand(bit_cast<int32_t>(kZapValue)));
|
||||
mov(offset, Operand(bit_cast<int32_t>(kZapValue)));
|
||||
mov(scratch, Operand(bit_cast<int32_t>(kZapValue)));
|
||||
mov(object, Operand(BitCast<int32_t>(kZapValue)));
|
||||
mov(offset, Operand(BitCast<int32_t>(kZapValue)));
|
||||
mov(scratch, Operand(BitCast<int32_t>(kZapValue)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ class SourceCodeCache BASE_EMBEDDED {
|
||||
}
|
||||
|
||||
void Iterate(ObjectVisitor* v) {
|
||||
v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
|
||||
v->VisitPointer(BitCast<Object**, FixedArray**>(&cache_));
|
||||
}
|
||||
|
||||
|
||||
|
@ -803,7 +803,7 @@ void Debug::PreemptionWhileInDebugger() {
|
||||
|
||||
|
||||
void Debug::Iterate(ObjectVisitor* v) {
|
||||
v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_)));
|
||||
v->VisitPointer(BitCast<Object**, Code**>(&(debug_break_return_)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,8 +34,8 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// We assume that doubles and uint64_t have the same endianness.
|
||||
static uint64_t double_to_uint64(double d) { return bit_cast<uint64_t>(d); }
|
||||
static double uint64_to_double(uint64_t d64) { return bit_cast<double>(d64); }
|
||||
static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
|
||||
static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
|
||||
|
||||
// Helper functions for doubles.
|
||||
class Double {
|
||||
|
@ -317,7 +317,7 @@ class Factory : public AllStatic {
|
||||
|
||||
#define ROOT_ACCESSOR(type, name, camel_name) \
|
||||
static inline Handle<type> name() { \
|
||||
return Handle<type>(bit_cast<type**, Object**>( \
|
||||
return Handle<type>(BitCast<type**, Object**>( \
|
||||
&Heap::roots_[Heap::k##camel_name##RootIndex])); \
|
||||
}
|
||||
ROOT_LIST(ROOT_ACCESSOR)
|
||||
@ -325,7 +325,7 @@ class Factory : public AllStatic {
|
||||
|
||||
#define SYMBOL_ACCESSOR(name, str) \
|
||||
static inline Handle<String> name() { \
|
||||
return Handle<String>(bit_cast<String**, Object**>( \
|
||||
return Handle<String>(BitCast<String**, Object**>( \
|
||||
&Heap::roots_[Heap::k##name##RootIndex])); \
|
||||
}
|
||||
SYMBOL_LIST(SYMBOL_ACCESSOR)
|
||||
|
@ -574,42 +574,6 @@ F FUNCTION_CAST(Address addr) {
|
||||
#define INLINE(header) inline header
|
||||
#endif
|
||||
|
||||
// The type-based aliasing rule allows the compiler to assume that pointers of
|
||||
// different types (for some definition of different) never alias each other.
|
||||
// Thus the following code does not work:
|
||||
//
|
||||
// float f = foo();
|
||||
// int fbits = *(int*)(&f);
|
||||
//
|
||||
// The compiler 'knows' that the int pointer can't refer to f since the types
|
||||
// don't match, so the compiler may cache f in a register, leaving random data
|
||||
// in fbits. Using C++ style casts makes no difference, however a pointer to
|
||||
// char data is assumed to alias any other pointer. This is the 'memcpy
|
||||
// exception'.
|
||||
//
|
||||
// Bit_cast uses the memcpy exception to move the bits from a variable of one
|
||||
// type of a variable of another type. Of course the end result is likely to
|
||||
// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
|
||||
// will completely optimize bit_cast away.
|
||||
//
|
||||
// There is an additional use for bit_cast.
|
||||
// Recent gccs will warn when they see casts that may result in breakage due to
|
||||
// the type-based aliasing rule. If you have checked that there is no breakage
|
||||
// you can use bit_cast to cast one pointer type to another. This confuses gcc
|
||||
// enough that it can no longer see that you have cast one pointer type to
|
||||
// another thus avoiding the warning.
|
||||
template <class Dest, class Source>
|
||||
inline Dest bit_cast(const Source& source) {
|
||||
// Compile time assertion: sizeof(Dest) == sizeof(Source)
|
||||
// A compile error here means your Dest and Source have different sizes.
|
||||
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
||||
|
||||
Dest dest;
|
||||
memcpy(&dest, &source, sizeof(dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
// Feature flags bit positions. They are mostly based on the CPUID spec.
|
||||
// (We assign CPUID itself to one of the currently reserved bits --
|
||||
// feel free to change this if needed.)
|
||||
|
@ -3399,7 +3399,7 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
|
||||
v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
|
||||
v->Synchronize("strong_root_list");
|
||||
|
||||
v->VisitPointer(bit_cast<Object**, String**>(&hidden_symbol_));
|
||||
v->VisitPointer(BitCast<Object**, String**>(&hidden_symbol_));
|
||||
v->Synchronize("symbol");
|
||||
|
||||
Bootstrapper::Iterate(v);
|
||||
|
@ -186,9 +186,9 @@ void MacroAssembler::RecordWrite(Register object, int offset,
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors.
|
||||
if (FLAG_debug_code) {
|
||||
mov(object, Immediate(bit_cast<int32_t>(kZapValue)));
|
||||
mov(value, Immediate(bit_cast<int32_t>(kZapValue)));
|
||||
mov(scratch, Immediate(bit_cast<int32_t>(kZapValue)));
|
||||
mov(object, Immediate(BitCast<int32_t>(kZapValue)));
|
||||
mov(value, Immediate(BitCast<int32_t>(kZapValue)));
|
||||
mov(scratch, Immediate(BitCast<int32_t>(kZapValue)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include "disasm.h"
|
||||
#include "assembler.h"
|
||||
#include "globals.h" // Need the bit_cast
|
||||
#include "globals.h" // Need the BitCast
|
||||
#include "mips/constants-mips.h"
|
||||
#include "mips/simulator-mips.h"
|
||||
|
||||
@ -604,7 +604,7 @@ void Simulator::set_fpu_register(int fpureg, int32_t value) {
|
||||
|
||||
void Simulator::set_fpu_register_double(int fpureg, double value) {
|
||||
ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
|
||||
*v8i::bit_cast<double*, int32_t*>(&FPUregisters_[fpureg]) = value;
|
||||
*v8i::BitCast<double*, int32_t*>(&FPUregisters_[fpureg]) = value;
|
||||
}
|
||||
|
||||
|
||||
@ -625,7 +625,7 @@ int32_t Simulator::get_fpu_register(int fpureg) const {
|
||||
|
||||
double Simulator::get_fpu_register_double(int fpureg) const {
|
||||
ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
|
||||
return *v8i::bit_cast<double*, int32_t*>(
|
||||
return *v8i::BitCast<double*, int32_t*>(
|
||||
const_cast<int32_t*>(&FPUregisters_[fpureg]));
|
||||
}
|
||||
|
||||
@ -901,7 +901,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
|
||||
break;
|
||||
case MFHC1:
|
||||
fp_out = get_fpu_register_double(fs_reg);
|
||||
alu_out = *v8i::bit_cast<int32_t*, double*>(&fp_out);
|
||||
alu_out = *v8i::BitCast<int32_t*, double*>(&fp_out);
|
||||
break;
|
||||
case MTC1:
|
||||
case MTHC1:
|
||||
|
@ -2154,24 +2154,24 @@ class Dictionary: public HashTable<Shape, Key> {
|
||||
|
||||
// Returns the value at entry.
|
||||
Object* ValueAt(int entry) {
|
||||
return get(HashTable<Shape, Key>::EntryToIndex(entry)+1);
|
||||
return this->get(HashTable<Shape, Key>::EntryToIndex(entry)+1);
|
||||
}
|
||||
|
||||
// Set the value for entry.
|
||||
void ValueAtPut(int entry, Object* value) {
|
||||
set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value);
|
||||
this->set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value);
|
||||
}
|
||||
|
||||
// Returns the property details for the property at entry.
|
||||
PropertyDetails DetailsAt(int entry) {
|
||||
ASSERT(entry >= 0); // Not found is -1, which is not caught by get().
|
||||
return PropertyDetails(
|
||||
Smi::cast(get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
|
||||
Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
|
||||
}
|
||||
|
||||
// Set the details for entry.
|
||||
void DetailsAtPut(int entry, PropertyDetails value) {
|
||||
set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
|
||||
this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
|
||||
}
|
||||
|
||||
// Sorting support
|
||||
@ -2194,7 +2194,7 @@ class Dictionary: public HashTable<Shape, Key> {
|
||||
|
||||
// Accessors for next enumeration index.
|
||||
void SetNextEnumerationIndex(int index) {
|
||||
fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index));
|
||||
this->fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index));
|
||||
}
|
||||
|
||||
int NextEnumerationIndex() {
|
||||
|
@ -92,15 +92,15 @@ void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
|
||||
v->VisitPointer(&(thread->pending_exception_));
|
||||
v->VisitPointer(&(thread->pending_message_obj_));
|
||||
v->VisitPointer(
|
||||
bit_cast<Object**, Script**>(&(thread->pending_message_script_)));
|
||||
v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_)));
|
||||
BitCast<Object**, Script**>(&(thread->pending_message_script_)));
|
||||
v->VisitPointer(BitCast<Object**, Context**>(&(thread->context_)));
|
||||
v->VisitPointer(&(thread->scheduled_exception_));
|
||||
|
||||
for (v8::TryCatch* block = thread->TryCatchHandler();
|
||||
block != NULL;
|
||||
block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
|
||||
v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_)));
|
||||
v->VisitPointer(bit_cast<Object**, void**>(&(block->message_)));
|
||||
v->VisitPointer(BitCast<Object**, void**>(&(block->exception_)));
|
||||
v->VisitPointer(BitCast<Object**, void**>(&(block->message_)));
|
||||
}
|
||||
|
||||
// Iterate over pointers on native execution stack.
|
||||
|
40
src/utils.h
40
src/utils.h
@ -29,6 +29,7 @@
|
||||
#define V8_UTILS_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -396,7 +397,7 @@ class EmbeddedVector : public Vector<T> {
|
||||
if (this == &rhs) return *this;
|
||||
Vector<T>::operator=(rhs);
|
||||
memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
|
||||
set_start(buffer_);
|
||||
this->set_start(buffer_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -599,6 +600,43 @@ static inline void MemsetPointer(T** dest, T* value, int counter) {
|
||||
// Calculate 10^exponent.
|
||||
int TenToThe(int exponent);
|
||||
|
||||
|
||||
// The type-based aliasing rule allows the compiler to assume that pointers of
|
||||
// different types (for some definition of different) never alias each other.
|
||||
// Thus the following code does not work:
|
||||
//
|
||||
// float f = foo();
|
||||
// int fbits = *(int*)(&f);
|
||||
//
|
||||
// The compiler 'knows' that the int pointer can't refer to f since the types
|
||||
// don't match, so the compiler may cache f in a register, leaving random data
|
||||
// in fbits. Using C++ style casts makes no difference, however a pointer to
|
||||
// char data is assumed to alias any other pointer. This is the 'memcpy
|
||||
// exception'.
|
||||
//
|
||||
// Bit_cast uses the memcpy exception to move the bits from a variable of one
|
||||
// type of a variable of another type. Of course the end result is likely to
|
||||
// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
|
||||
// will completely optimize BitCast away.
|
||||
//
|
||||
// There is an additional use for BitCast.
|
||||
// Recent gccs will warn when they see casts that may result in breakage due to
|
||||
// the type-based aliasing rule. If you have checked that there is no breakage
|
||||
// you can use BitCast to cast one pointer type to another. This confuses gcc
|
||||
// enough that it can no longer see that you have cast one pointer type to
|
||||
// another thus avoiding the warning.
|
||||
template <class Dest, class Source>
|
||||
inline Dest BitCast(const Source& source) {
|
||||
// Compile time assertion: sizeof(Dest) == sizeof(Source)
|
||||
// A compile error here means your Dest and Source have different sizes.
|
||||
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
||||
|
||||
Dest dest;
|
||||
memcpy(&dest, &source, sizeof(dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_UTILS_H_
|
||||
|
@ -197,9 +197,9 @@ void MacroAssembler::RecordWrite(Register object,
|
||||
// avoid having the fast case for smis leave the registers
|
||||
// unchanged.
|
||||
if (FLAG_debug_code) {
|
||||
movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(value, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(smi_index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,9 +270,9 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors.
|
||||
if (FLAG_debug_code) {
|
||||
movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(scratch, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(smi_index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user