From e9e291c3312b109bc42091799d062c327c2856c6 Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Thu, 12 Apr 2012 09:23:26 +0000 Subject: [PATCH] MIPS: NaNs in the snapshot should be quiet according to the MIPS FPU even when cross-building the snapshot. This is based on code from Daniel Kalmar from http://codereview.chromium.org/9910029/ Review URL: https://chromiumcodereview.appspot.com/10068006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11283 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/assembler.h | 4 ++++ src/mips/assembler-mips.cc | 16 ++++++++++++++++ src/mips/assembler-mips.h | 2 ++ src/serialize.cc | 2 ++ 4 files changed, 24 insertions(+) diff --git a/src/assembler.h b/src/assembler.h index 6deca26..05fe320 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -62,6 +62,10 @@ class AssemblerBase: public Malloced { Isolate* isolate() const { return isolate_; } int jit_cookie() { return jit_cookie_; } + // Overwrite a host NaN with a quiet target NaN. Used by mksnapshot for + // cross-snapshotting. + static void QuietNaN(HeapObject* nan) { } + private: Isolate* isolate_; int jit_cookie_; diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc index fa64e1e..cc82097 100644 --- a/src/mips/assembler-mips.cc +++ b/src/mips/assembler-mips.cc @@ -2137,6 +2137,22 @@ Address Assembler::target_address_at(Address pc) { } +#define MIPS_QNAN_HI 0x7ff7ffff +#define MIPS_QNAN_LO 0xffffffff + + +void Assembler::QuietNaN(HeapObject* object) { + // Mips has a different encoding of qNaN than ia32, so any heap NaN built + // with simulator must be re-encoded for the snapshot. Performance hit not + // critical at mksnapshot/build time. We can't use set_value because that + // will put the NaN in an fp register, which changes the bits. + uint64_t mips_qnan_bits = + (static_cast(MIPS_QNAN_HI) << 32) | MIPS_QNAN_LO; + Address value_ptr = object->address() + HeapNumber::kValueOffset; + memcpy(value_ptr, &mips_qnan_bits, sizeof(mips_qnan_bits)); +} + + // On Mips, a target address is stored in a lui/ori instruction pair, each // of which load 16 bits of the 32-bit address to a register. // Patching the address must replace both instr, and flush the i-cache. diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h index 5e67d0c..84714e5 100644 --- a/src/mips/assembler-mips.h +++ b/src/mips/assembler-mips.h @@ -570,6 +570,8 @@ class Assembler : public AssemblerBase { static void JumpLabelToJumpRegister(Address pc); + static void QuietNaN(HeapObject* nan); + // This sets the branch destination (which gets loaded at the call address). // This is for calls and branches within generated code. The serializer // has already deserialized the lui/ori instructions etc. diff --git a/src/serialize.cc b/src/serialize.cc index 01d5f1c..c6f9971 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -1444,6 +1444,8 @@ void Serializer::ObjectSerializer::Serialize() { sink_->PutSection(space, "NewPageSpace"); } + if (object_->IsNaN()) Assembler::QuietNaN(object_); + // Serialize the map (first word of the object). serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject); -- 2.7.4