diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 321ba00560..e277c7a1ad 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,15 @@ +2010-06-07: Version 2.2.16 + + Remove the SetExternalStringDiposeCallback API. Changed the + disposal of external string resources to call a virtual Dispose + method on the resource. + + Added support for more precise break points when debugging and + stepping. + + Memory usage improvements on all platforms. + + 2010-06-07: Version 2.2.15 Add an API to control the disposal of external string resources. diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index fe01e30cf6..24b4cbe37d 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -134,6 +134,7 @@ namespace internal { class Arguments; class Object; +class Heap; class Top; } @@ -513,6 +514,7 @@ class V8EXPORT Data { class V8EXPORT ScriptData { // NOLINT public: virtual ~ScriptData() { } + /** * Pre-compiles the specified script (context-independent). * @@ -521,6 +523,16 @@ class V8EXPORT ScriptData { // NOLINT */ static ScriptData* PreCompile(const char* input, int length); + /** + * Pre-compiles the specified script (context-independent). + * + * NOTE: Pre-compilation using this method cannot happen on another thread + * without using Lockers. + * + * \param source Script source code. + */ + static ScriptData* PreCompile(Handle source); + /** * Load previous pre-compilation data. * @@ -1026,12 +1038,24 @@ class V8EXPORT String : public Primitive { class V8EXPORT ExternalStringResourceBase { public: virtual ~ExternalStringResourceBase() {} + protected: ExternalStringResourceBase() {} + + /** + * Internally V8 will call this Dispose method when the external string + * resource is no longer needed. The default implementation will use the + * delete operator. This method can be overridden in subclasses to + * control how allocated external string resources are disposed. + */ + virtual void Dispose() { delete this; } + private: // Disallow copying and assigning. ExternalStringResourceBase(const ExternalStringResourceBase&); void operator=(const ExternalStringResourceBase&); + + friend class v8::internal::Heap; }; /** @@ -1048,10 +1072,17 @@ class V8EXPORT String : public Primitive { * buffer. */ virtual ~ExternalStringResource() {} - /** The string data from the underlying buffer.*/ + + /** + * The string data from the underlying buffer. + */ virtual const uint16_t* data() const = 0; - /** The length of the string. That is, the number of two-byte characters.*/ + + /** + * The length of the string. That is, the number of two-byte characters. + */ virtual size_t length() const = 0; + protected: ExternalStringResource() {} }; @@ -1123,12 +1154,10 @@ class V8EXPORT String : public Primitive { /** * Creates a new external string using the data defined in the given * resource. When the external string is no longer live on V8's heap the - * resource will be disposed. If a disposal callback has been set using - * SetExternalStringDiposeCallback this callback will be called to dispose - * the resource. Otherwise, V8 will dispose the resource using the C++ delete - * operator. The caller of this function should not otherwise delete or - * modify the resource. Neither should the underlying buffer be deallocated - * or modified except through the destructor of the external string resource. + * resource will be disposed by calling its Dispose method. The caller of + * this function should not otherwise delete or modify the resource. Neither + * should the underlying buffer be deallocated or modified except through the + * destructor of the external string resource. */ static Local NewExternal(ExternalStringResource* resource); @@ -1146,12 +1175,10 @@ class V8EXPORT String : public Primitive { /** * Creates a new external string using the ascii data defined in the given * resource. When the external string is no longer live on V8's heap the - * resource will be disposed. If a disposal callback has been set using - * SetExternalStringDiposeCallback this callback will be called to dispose - * the resource. Otherwise, V8 will dispose the resource using the C++ delete - * operator. The caller of this function should not otherwise delete or - * modify the resource. Neither should the underlying buffer be deallocated - * or modified except through the destructor of the external string resource. + * resource will be disposed by calling its Dispose method. The caller of + * this function should not otherwise delete or modify the resource. Neither + * should the underlying buffer be deallocated or modified except through the + * destructor of the external string resource. */ static Local NewExternal(ExternalAsciiStringResource* resource); @@ -1251,10 +1278,6 @@ class V8EXPORT String : public Primitive { }; -typedef void (*ExternalStringDiposeCallback) - (String::ExternalStringResourceBase* resource); - - /** * A JavaScript number value (ECMA-262, 4.3.20) */ @@ -2471,15 +2494,6 @@ class V8EXPORT V8 { */ static void RemoveMessageListeners(MessageCallback that); - /** - * Set a callback to be called when an external string is no longer live on - * V8's heap. The resource will no longer be needed by V8 and the embedder - * can dispose of if. If this callback is not set V8 will free the resource - * using the C++ delete operator. - */ - static void SetExternalStringDiposeCallback( - ExternalStringDiposeCallback that); - /** * Sets V8 flags from a string. */ diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index dfdd7bd7b2..cb5e96df93 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -1120,6 +1120,12 @@ ScriptData* ScriptData::PreCompile(const char* input, int length) { } +ScriptData* ScriptData::PreCompile(v8::Handle source) { + i::Handle str = Utils::OpenHandle(*source); + return i::PreParse(str, NULL, NULL); +} + + ScriptData* ScriptData::New(const char* data, int length) { // Return an empty ScriptData if the length is obviously invalid. if (length % sizeof(unsigned) != 0) { @@ -3692,14 +3698,6 @@ void V8::RemoveMessageListeners(MessageCallback that) { } -void V8::SetExternalStringDiposeCallback( - ExternalStringDiposeCallback callback) { - if (IsDeadCheck("v8::V8::SetExternalStringDiposeCallback()")) - return; - i::Heap::SetExternalStringDiposeCallback(callback); -} - - void V8::SetCounterFunction(CounterLookupCallback callback) { if (IsDeadCheck("v8::V8::SetCounterFunction()")) return; i::StatsTable::SetCounterFunction(callback); diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h index e292cefabf..8ca91265ba 100644 --- a/deps/v8/src/arm/assembler-arm-inl.h +++ b/deps/v8/src/arm/assembler-arm-inl.h @@ -116,9 +116,10 @@ Address* RelocInfo::target_reference_address() { Address RelocInfo::call_address() { - ASSERT(IsPatchedReturnSequence()); - // The 2 instructions offset assumes patched return sequence. - ASSERT(IsJSReturn(rmode())); + // The 2 instructions offset assumes patched debug break slot or return + // sequence. + ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || + (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); } @@ -168,6 +169,12 @@ bool RelocInfo::IsPatchedReturnSequence() { } +bool RelocInfo::IsPatchedDebugBreakSlotSequence() { + Instr current_instr = Assembler::instr_at(pc_); + return !Assembler::IsNop(current_instr, 2); +} + + void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { @@ -178,8 +185,10 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { visitor->VisitExternalReference(target_reference_address()); #ifdef ENABLE_DEBUGGER_SUPPORT } else if (Debug::has_break_points() && - RelocInfo::IsJSReturn(mode) && - IsPatchedReturnSequence()) { + ((RelocInfo::IsJSReturn(mode) && + IsPatchedReturnSequence()) || + (RelocInfo::IsDebugBreakSlot(mode) && + IsPatchedDebugBreakSlotSequence()))) { visitor->VisitDebugTarget(this); #endif } else if (mode == RelocInfo::RUNTIME_ENTRY) { diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index 846464ab5a..025f28e551 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -2040,6 +2040,13 @@ void Assembler::RecordJSReturn() { } +void Assembler::RecordDebugBreakSlot() { + WriteRecordedPositions(); + CheckBuffer(); + RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); +} + + void Assembler::RecordComment(const char* msg) { if (FLAG_debug_code) { CheckBuffer(); @@ -2062,13 +2069,16 @@ void Assembler::RecordStatementPosition(int pos) { } -void Assembler::WriteRecordedPositions() { +bool Assembler::WriteRecordedPositions() { + bool written = false; + // Write the statement position if it is different from what was written last // time. if (current_statement_position_ != written_statement_position_) { CheckBuffer(); RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_); written_statement_position_ = current_statement_position_; + written = true; } // Write the position if it is different from what was written last time and @@ -2078,7 +2088,11 @@ void Assembler::WriteRecordedPositions() { CheckBuffer(); RecordRelocInfo(RelocInfo::POSITION, current_position_); written_position_ = current_position_; + written = true; } + + // Return whether something was written. + return written; } @@ -2135,9 +2149,10 @@ void Assembler::GrowBuffer() { void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants - if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::STATEMENT_POSITION) { + if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) { // Adjust code for new modes. - ASSERT(RelocInfo::IsJSReturn(rmode) + ASSERT(RelocInfo::IsDebugBreakSlot(rmode) + || RelocInfo::IsJSReturn(rmode) || RelocInfo::IsComment(rmode) || RelocInfo::IsPosition(rmode)); // These modes do not need an entry in the constant pool. diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h index d0dee561cf..e5d42f9a5e 100644 --- a/deps/v8/src/arm/assembler-arm.h +++ b/deps/v8/src/arm/assembler-arm.h @@ -629,22 +629,39 @@ class Assembler : public Malloced { // Distance between start of patched return sequence and the emitted address // to jump to. #ifdef USE_BLX - // Return sequence is: + // Patched return sequence is: // ldr ip, [pc, #0] @ emited address and start // blx ip static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize; #else - // Return sequence is: + // Patched return sequence is: // mov lr, pc @ start of sequence // ldr pc, [pc, #-4] @ emited address static const int kPatchReturnSequenceAddressOffset = kInstrSize; #endif + // Distance between start of patched debug break slot and the emitted address + // to jump to. +#ifdef USE_BLX + // Patched debug break slot code is: + // ldr ip, [pc, #0] @ emited address and start + // blx ip + static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; +#else + // Patched debug break slot code is: + // mov lr, pc @ start of sequence + // ldr pc, [pc, #-4] @ emited address + static const int kPatchDebugBreakSlotAddressOffset = kInstrSize; +#endif + // Difference between address of current opcode and value read from pc // register. static const int kPcLoadDelta = 8; - static const int kJSReturnSequenceLength = 4; + static const int kJSReturnSequenceInstructions = 4; + static const int kDebugBreakSlotInstructions = 3; + static const int kDebugBreakSlotLength = + kDebugBreakSlotInstructions * kInstrSize; // --------------------------------------------------------------------------- // Code generation @@ -981,13 +998,16 @@ class Assembler : public Malloced { // Mark address of the ExitJSFrame code. void RecordJSReturn(); + // Mark address of a debug break slot. + void RecordDebugBreakSlot(); + // Record a comment relocation entry that can be used by a disassembler. // Use --debug_code to enable. void RecordComment(const char* msg); void RecordPosition(int pos); void RecordStatementPosition(int pos); - void WriteRecordedPositions(); + bool WriteRecordedPositions(); int pc_offset() const { return pc_ - buffer_; } int current_position() const { return current_position_; } diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index d6fdf459ce..8d4bf14c98 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -386,8 +386,10 @@ void CodeGenerator::Generate(CompilationInfo* info) { // the add instruction the add will generate two instructions. int return_sequence_length = masm_->InstructionsGeneratedSince(&check_exit_codesize); - CHECK(return_sequence_length == Assembler::kJSReturnSequenceLength || - return_sequence_length == Assembler::kJSReturnSequenceLength + 1); + CHECK(return_sequence_length == + Assembler::kJSReturnSequenceInstructions || + return_sequence_length == + Assembler::kJSReturnSequenceInstructions + 1); #endif } } diff --git a/deps/v8/src/arm/codegen-arm.h b/deps/v8/src/arm/codegen-arm.h index 6a33667eb4..cabdf007b9 100644 --- a/deps/v8/src/arm/codegen-arm.h +++ b/deps/v8/src/arm/codegen-arm.h @@ -226,7 +226,9 @@ class CodeGenerator: public AstVisitor { bool is_toplevel, Handle