Browse Source

Upgrade V8 to 2.5.9.1

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
7286b79521
  1. 1
      deps/v8/AUTHORS
  2. 25
      deps/v8/ChangeLog
  3. 5
      deps/v8/include/v8.h
  4. 227
      deps/v8/preparser/preparser-process.cc
  5. 18
      deps/v8/samples/process.cc
  6. 14
      deps/v8/samples/shell.cc
  7. 2
      deps/v8/src/SConscript
  8. 9
      deps/v8/src/api.cc
  9. 6
      deps/v8/src/arm/assembler-arm-inl.h
  10. 25
      deps/v8/src/arm/assembler-arm.cc
  11. 20
      deps/v8/src/arm/assembler-arm.h
  12. 125
      deps/v8/src/arm/builtins-arm.cc
  13. 288
      deps/v8/src/arm/codegen-arm.cc
  14. 8
      deps/v8/src/arm/codegen-arm.h
  15. 2
      deps/v8/src/arm/debug-arm.cc
  16. 79
      deps/v8/src/arm/ic-arm.cc
  17. 27
      deps/v8/src/arm/macro-assembler-arm.cc
  18. 42
      deps/v8/src/arm/macro-assembler-arm.h
  19. 7
      deps/v8/src/arm/stub-cache-arm.cc
  20. 1
      deps/v8/src/checks.cc
  21. 34
      deps/v8/src/checks.h
  22. 6
      deps/v8/src/conversions.cc
  23. 2
      deps/v8/src/dateparser-inl.h
  24. 12
      deps/v8/src/dateparser.h
  25. 2
      deps/v8/src/handles.cc
  26. 8
      deps/v8/src/hashmap.cc
  27. 10
      deps/v8/src/heap-profiler.cc
  28. 8
      deps/v8/src/ia32/macro-assembler-ia32.cc
  29. 1
      deps/v8/src/ia32/macro-assembler-ia32.h
  30. 7
      deps/v8/src/ia32/stub-cache-ia32.cc
  31. 11
      deps/v8/src/log.cc
  32. 3
      deps/v8/src/objects.cc
  33. 193
      deps/v8/src/parser.cc
  34. 151
      deps/v8/src/parser.h
  35. 3
      deps/v8/src/platform-freebsd.cc
  36. 3
      deps/v8/src/platform-linux.cc
  37. 3
      deps/v8/src/platform-macos.cc
  38. 6
      deps/v8/src/platform-openbsd.cc
  39. 3
      deps/v8/src/platform-solaris.cc
  40. 3
      deps/v8/src/platform-win32.cc
  41. 17
      deps/v8/src/platform.h
  42. 180
      deps/v8/src/preparse-data.cc
  43. 223
      deps/v8/src/preparse-data.h
  44. 1184
      deps/v8/src/preparser.cc
  45. 1188
      deps/v8/src/preparser.h
  46. 23
      deps/v8/src/profile-generator.cc
  47. 4
      deps/v8/src/profile-generator.h
  48. 8
      deps/v8/src/runtime.cc
  49. 2
      deps/v8/src/runtime.h
  50. 2
      deps/v8/src/string.js
  51. 2
      deps/v8/src/stub-cache.h
  52. 3
      deps/v8/src/token.cc
  53. 2
      deps/v8/src/v8.h
  54. 64
      deps/v8/src/v8checks.h
  55. 4
      deps/v8/src/version.cc
  56. 8
      deps/v8/src/x64/macro-assembler-x64.cc
  57. 3
      deps/v8/src/x64/macro-assembler-x64.h
  58. 7
      deps/v8/src/x64/stub-cache-x64.cc
  59. 27
      deps/v8/test/cctest/test-api.cc
  60. 6
      deps/v8/test/cctest/test-conversions.cc
  61. 15
      deps/v8/test/cctest/test-heap-profiler.cc
  62. 42
      deps/v8/test/cctest/test-log.cc
  63. 3
      deps/v8/test/cctest/test-parsing.cc
  64. 46
      deps/v8/test/mjsunit/regress/regress-944.js
  65. 19
      deps/v8/test/mjsunit/string-split.js
  66. 7
      deps/v8/tools/gyp/v8.gyp
  67. 2
      deps/v8/tools/presubmit.py
  68. 32
      deps/v8/tools/visual_studio/v8_base.vcproj

1
deps/v8/AUTHORS

@ -9,7 +9,6 @@ ARM Ltd.
Hewlett-Packard Development Company, LP
Alexander Botero-Lowry <alexbl@FreeBSD.org>
Alexandre Rames <alexandre.rames@arm.com>
Alexandre Vassalotti <avassalotti@gmail.com>
Andreas Anyuru <andreas.anyuru@gmail.com>
Burcu Dogan <burcujdogan@gmail.com>

25
deps/v8/ChangeLog

@ -1,3 +1,28 @@
2010-11-29: Version 2.5.9
Fixed crashes during GC caused by partially initialize heap
objects.
Fixed bug in process sample that caused memory leaks.
Improved performance on ARM by implementing missing stubs and
inlining.
Improved heap profiler support.
Added separate seeding on Windows of the random number generator
used internally by the compiler (issue 936).
Exposed API for getting the name of the function used to construct
an object.
Fixed date parser to handle one and two digit millisecond
values (issue 944).
Fixed number parsing to disallow space between sign and
digits (issue 946).
2010-11-23: Version 2.5.8
Removed dependency on Gay's dtoa.

5
deps/v8/include/v8.h

@ -1539,6 +1539,11 @@ class Object : public Value {
*/
V8EXPORT Local<String> ObjectProtoToString();
/**
* Returns the name of the function invoked as a constructor for this object.
*/
V8EXPORT Local<String> GetConstructorName();
/** Gets the number of internal fields for this Object. */
V8EXPORT int InternalFieldCount();
/** Gets the value in an internal field. */

227
deps/v8/preparser/preparser-process.cc

@ -0,0 +1,227 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdarg.h>
#include "../include/v8stdint.h"
#include "globals.h"
#include "checks.h"
#include "allocation.h"
#include "utils.h"
#include "list.h"
#include "smart-pointer.h"
#include "scanner-base.h"
#include "preparse-data.h"
#include "preparser.h"
enum ResultCode { kSuccess = 0, kErrorReading = 1, kErrorWriting = 2 };
namespace v8 {
namespace internal {
// THIS FILE IS PROOF-OF-CONCEPT ONLY.
// The final goal is a stand-alone preparser library.
// UTF16Buffer based on an UTF-8 string in memory.
class UTF8UTF16Buffer : public UTF16Buffer {
public:
UTF8UTF16Buffer(uint8_t* buffer, size_t length)
: UTF16Buffer(),
buffer_(buffer),
offset_(0),
end_offset_(static_cast<int>(length)) { }
virtual void PushBack(uc32 ch) {
// Pushback assumes that the character pushed back is the
// one that was most recently read, and jumps back in the
// UTF-8 stream by the length of that character's encoding.
offset_ -= unibrow::Utf8::Length(ch);
pos_--;
#ifdef DEBUG
int tmp = 0;
ASSERT_EQ(ch, unibrow::Utf8::ValueOf(buffer_ + offset_,
end_offset_ - offset_,
&tmp);
#endif
}
virtual uc32 Advance() {
if (offset_ == end_offset_) return -1;
uint8_t first_char = buffer_[offset_];
if (first_char <= unibrow::Utf8::kMaxOneByteChar) {
pos_++;
offset_++;
return static_cast<uc32>(first_char);
}
unibrow::uchar codepoint =
unibrow::Utf8::CalculateValue(buffer_ + offset_,
end_offset_ - offset_,
&offset_);
pos_++;
return static_cast<uc32>(codepoint);
}
virtual void SeekForward(int pos) {
while (pos_ < pos) {
uint8_t first_byte = buffer_[offset_++];
while (first_byte & 0x80u && offset_ < end_offset_) {
offset_++;
first_byte <<= 1;
}
pos_++;
}
}
private:
const uint8_t* buffer_;
unsigned offset_;
unsigned end_offset_;
};
class StandAloneJavaScriptScanner : public JavaScriptScanner {
public:
void Initialize(UTF16Buffer* source) {
source_ = source;
literal_flags_ = kLiteralString | kLiteralIdentifier;
Init();
// Skip initial whitespace allowing HTML comment ends just like
// after a newline and scan first token.
has_line_terminator_before_next_ = true;
SkipWhiteSpace();
Scan();
}
};
// Write a number to dest in network byte order.
void WriteUInt32(FILE* dest, uint32_t value, bool* ok) {
for (int i = 3; i >= 0; i--) {
uint8_t byte = static_cast<uint8_t>(value >> (i << 3));
int result = fputc(byte, dest);
if (result == EOF) {
*ok = false;
return;
}
}
}
// Read number from FILE* in network byte order.
uint32_t ReadUInt32(FILE* source, bool* ok) {
uint32_t n = 0;
for (int i = 0; i < 4; i++) {
int c = fgetc(source);
if (c == EOF) {
*ok = false;
return 0;
}
n = (n << 8) + static_cast<uint32_t>(c);
}
return n;
}
bool ReadBuffer(FILE* source, void* buffer, size_t length) {
size_t actually_read = fread(buffer, 1, length, stdin);
return (actually_read == length);
}
bool WriteBuffer(FILE* dest, void* buffer, size_t length) {
size_t actually_written = fwrite(buffer, 1, length, dest);
return (actually_written == length);
}
// Preparse stdin and output result on stdout.
int PreParseIO() {
fprintf(stderr, "LOG: Enter parsing loop\n");
bool ok = true;
uint32_t length = ReadUInt32(stdin, &ok);
if (!ok) return kErrorReading;
SmartPointer<byte> buffer(NewArray<byte>(length));
if (!ReadBuffer(stdin, *buffer, length)) {
return kErrorReading;
}
UTF8UTF16Buffer input_buffer(*buffer, static_cast<size_t>(length));
StandAloneJavaScriptScanner scanner;
scanner.Initialize(&input_buffer);
CompleteParserRecorder recorder;
preparser::PreParser preparser;
if (!preparser.PreParseProgram(&scanner, &recorder, true)) {
if (scanner.stack_overflow()) {
// Report stack overflow error/no-preparser-data.
WriteUInt32(stdout, 0, &ok);
if (!ok) return kErrorWriting;
return 0;
}
}
Vector<unsigned> pre_data = recorder.ExtractData();
uint32_t size = static_cast<uint32_t>(pre_data.length() * sizeof(uint32_t));
WriteUInt32(stdout, size, &ok);
if (!ok) return kErrorWriting;
if (!WriteBuffer(stdout,
reinterpret_cast<byte*>(pre_data.start()),
size)) {
return kErrorWriting;
}
return 0;
}
// Functions declared by allocation.h
void FatalProcessOutOfMemory(const char* location) {
V8_Fatal("", 0, location);
}
bool EnableSlowAsserts() { return true; }
} } // namespace v8::internal
int main(int argc, char* argv[]) {
int status = 0;
do {
status = v8::internal::PreParseIO();
} while (status == 0);
fprintf(stderr, "EXIT: Failure %d\n", status);
return EXIT_FAILURE;
}
// Fatal error handling declared by checks.h.
extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
fflush(stdout);
fflush(stderr);
va_list arguments;
va_start(arguments, format);
vfprintf(stderr, format, arguments);
va_end(arguments);
fputs("\n#\n\n", stderr);
exit(EXIT_FAILURE);
}

18
deps/v8/samples/process.cc

@ -152,18 +152,16 @@ bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("log"), FunctionTemplate::New(LogCallback));
// Each processor gets its own context so different processors
// don't affect each other (ignore the first three lines).
Handle<Context> context = Context::New(NULL, global);
// Store the context in the processor object in a persistent handle,
// since we want the reference to remain after we return from this
// method.
context_ = Persistent<Context>::New(context);
// Each processor gets its own context so different processors don't
// affect each other. Context::New returns a persistent handle which
// is what we need for the reference to remain after we return from
// this method. That persistent handle has to be disposed in the
// destructor.
context_ = Context::New(NULL, global);
// Enter the new context so all the following operations take place
// within it.
Context::Scope context_scope(context);
Context::Scope context_scope(context_);
// Make the options mapping available within the context
if (!InstallMaps(opts, output))
@ -176,7 +174,7 @@ bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
// The script compiled and ran correctly. Now we fetch out the
// Process function from the global object.
Handle<String> process_name = String::New("Process");
Handle<Value> process_val = context->Global()->Get(process_name);
Handle<Value> process_val = context_->Global()->Get(process_name);
// If there is no Process function, or if it is not a function,
// bail out

14
deps/v8/samples/shell.cc

@ -37,7 +37,6 @@ bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name,
bool print_result,
bool report_exceptions);
v8::Handle<v8::Value> PrintToInteger(const v8::Arguments& args);
v8::Handle<v8::Value> Print(const v8::Arguments& args);
v8::Handle<v8::Value> Read(const v8::Arguments& args);
v8::Handle<v8::Value> Load(const v8::Arguments& args);
@ -54,8 +53,7 @@ int RunMain(int argc, char* argv[]) {
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// Bind the global 'print' function to the C++ Print callback.
global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
global->Set(v8::String::New("print2int"), v8::FunctionTemplate::New(PrintToInteger));
// Bind the global 'read' function to the C++ Read callback.
// Bind the global 'read' function to the C++ Read callback.
global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
// Bind the global 'load' function to the C++ Load callback.
global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
@ -140,16 +138,6 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
}
v8::Handle<v8::Value> PrintToInteger(const v8::Arguments& args) {
v8::HandleScope handle_scope;
v8::String::Utf8Value str(args[0]);
const char* cstr = ToCString(str);
printf("%s -> %d\n", cstr, args[0]->ToInt32()->Value());
fflush(stdout);
return v8::Undefined();
}
// The callback that is invoked by v8 whenever the JavaScript 'read'
// function is called. This function loads the content of the file named in
// the argument into a JavaScript string.

2
deps/v8/src/SConscript

@ -89,6 +89,8 @@ SOURCES = {
objects-visiting.cc
oprofile-agent.cc
parser.cc
preparser.cc
preparse-data.cc
profile-generator.cc
property.cc
regexp-macro-assembler-irregexp.cc

9
deps/v8/src/api.cc

@ -2451,6 +2451,15 @@ Local<String> v8::Object::ObjectProtoToString() {
}
Local<String> v8::Object::GetConstructorName() {
ON_BAILOUT("v8::Object::GetConstructorName()", return Local<v8::String>());
ENTER_V8;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> name(self->constructor_name());
return Utils::ToLocal(name);
}
bool v8::Object::Delete(v8::Handle<String> key) {
ON_BAILOUT("v8::Object::Delete()", return false);
ENTER_V8;

6
deps/v8/src/arm/assembler-arm-inl.h

@ -164,7 +164,7 @@ bool RelocInfo::IsPatchedReturnSequence() {
bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
Instr current_instr = Assembler::instr_at(pc_);
return !Assembler::IsNop(current_instr, 2);
return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
}
@ -288,9 +288,7 @@ Address Assembler::target_address_address_at(Address pc) {
}
#endif
// Verify that the instruction to patch is a
// ldr<cond> <Rd>, [pc +/- offset_12].
ASSERT((instr & 0x0f7f0000) == 0x051f0000);
ASSERT(IsLdrPcImmediateOffset(instr));
int offset = instr & 0xfff; // offset_12 is unsigned
if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign
// Verify that the constant pool comes after the instruction referencing it.

25
deps/v8/src/arm/assembler-arm.cc

@ -397,13 +397,6 @@ void Assembler::CodeTargetAlign() {
}
bool Assembler::IsNop(Instr instr, int type) {
// Check for mov rx, rx.
ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop.
return instr == (al | 13*B21 | type*B12 | type);
}
bool Assembler::IsBranch(Instr instr) {
return (instr & (B27 | B25)) == (B27 | B25);
}
@ -510,6 +503,13 @@ bool Assembler::IsLdrRegFpNegOffset(Instr instr) {
}
bool Assembler::IsLdrPcImmediateOffset(Instr instr) {
// Check the instruction is indeed a
// ldr<cond> <Rd>, [pc +/- offset_12].
return (instr & 0x0f7f0000) == 0x051f0000;
}
// Labels refer to positions in the (to be) generated code.
// There are bound, linked, and unused labels.
//
@ -1113,8 +1113,8 @@ void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
positions_recorder()->WriteRecordedPositions();
}
// Don't allow nop instructions in the form mov rn, rn to be generated using
// the mov instruction. They must be generated using nop(int)
// pseudo instructions.
// the mov instruction. They must be generated using nop(int/NopMarkerTypes)
// or MarkCode(int/NopMarkerTypes) pseudo instructions.
ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
addrmod1(cond | 13*B21 | s, r0, dst, src);
}
@ -2376,6 +2376,13 @@ void Assembler::nop(int type) {
}
bool Assembler::IsNop(Instr instr, int type) {
// Check for mov rx, rx.
ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop.
return instr == (al | 13*B21 | type*B12 | type);
}
bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
uint32_t dummy1;
uint32_t dummy2;

20
deps/v8/src/arm/assembler-arm.h

@ -1079,7 +1079,22 @@ class Assembler : public Malloced {
const Condition cond = al);
// Pseudo instructions
void nop(int type = 0);
// Different nop operations are used by the code generator to detect certain
// states of the generated code.
enum NopMarkerTypes {
NON_MARKING_NOP = 0,
DEBUG_BREAK_NOP,
// IC markers.
PROPERTY_ACCESS_INLINED,
PROPERTY_ACCESS_INLINED_CONTEXT,
PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
// Helper values.
LAST_CODE_MARKER,
FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
};
void nop(int type = 0); // 0 is the default non-marking type.
void push(Register src, Condition cond = al) {
str(src, MemOperand(sp, 4, NegPreIndex), cond);
@ -1151,7 +1166,6 @@ class Assembler : public Malloced {
static void instr_at_put(byte* pc, Instr instr) {
*reinterpret_cast<Instr*>(pc) = instr;
}
static bool IsNop(Instr instr, int type = 0);
static bool IsBranch(Instr instr);
static int GetBranchOffset(Instr instr);
static bool IsLdrRegisterImmediate(Instr instr);
@ -1168,6 +1182,8 @@ class Assembler : public Malloced {
static bool IsLdrRegFpOffset(Instr instr);
static bool IsStrRegFpNegOffset(Instr instr);
static bool IsLdrRegFpNegOffset(Instr instr);
static bool IsLdrPcImmediateOffset(Instr instr);
static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
protected:

125
deps/v8/src/arm/builtins-arm.cc

@ -482,9 +482,128 @@ void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) {
void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
// TODO(849): implement custom construct stub.
// Generate a copy of the generic stub for now.
Generate_JSConstructStubGeneric(masm);
// ----------- S t a t e -------------
// -- r0 : number of arguments
// -- r1 : constructor function
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
// -----------------------------------
__ IncrementCounter(&Counters::string_ctor_calls, 1, r2, r3);
Register function = r1;
if (FLAG_debug_code) {
__ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r2);
__ cmp(function, Operand(r2));
__ Assert(eq, "Unexpected String function");
}
// Load the first arguments in r0 and get rid of the rest.
Label no_arguments;
__ cmp(r0, Operand(0));
__ b(eq, &no_arguments);
// First args = sp[(argc - 1) * 4].
__ sub(r0, r0, Operand(1));
__ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex));
// sp now point to args[0], drop args[0] + receiver.
__ Drop(2);
Register argument = r2;
Label not_cached, argument_is_string;
NumberToStringStub::GenerateLookupNumberStringCache(
masm,
r0, // Input.
argument, // Result.
r3, // Scratch.
r4, // Scratch.
r5, // Scratch.
false, // Is it a Smi?
&not_cached);
__ IncrementCounter(&Counters::string_ctor_cached_number, 1, r3, r4);
__ bind(&argument_is_string);
// ----------- S t a t e -------------
// -- r2 : argument converted to string
// -- r1 : constructor function
// -- lr : return address
// -----------------------------------
Label gc_required;
__ AllocateInNewSpace(JSValue::kSize,
r0, // Result.
r3, // Scratch.
r4, // Scratch.
&gc_required,
TAG_OBJECT);
// Initialising the String Object.
Register map = r3;
__ LoadGlobalFunctionInitialMap(function, map, r4);
if (FLAG_debug_code) {
__ ldrb(r4, FieldMemOperand(map, Map::kInstanceSizeOffset));
__ cmp(r4, Operand(JSValue::kSize >> kPointerSizeLog2));
__ Assert(eq, "Unexpected string wrapper instance size");
__ ldrb(r4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset));
__ cmp(r4, Operand(0));
__ Assert(eq, "Unexpected unused properties of string wrapper");
}
__ str(map, FieldMemOperand(r0, HeapObject::kMapOffset));
__ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex);
__ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset));
__ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
__ str(argument, FieldMemOperand(r0, JSValue::kValueOffset));
// Ensure the object is fully initialized.
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
__ Ret();
// The argument was not found in the number to string cache. Check
// if it's a string already before calling the conversion builtin.
Label convert_argument;
__ bind(&not_cached);
__ BranchOnSmi(r0, &convert_argument);
// Is it a String?
__ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
__ ldrb(r3, FieldMemOperand(r2, Map::kInstanceTypeOffset));
ASSERT(kNotStringTag != 0);
__ tst(r3, Operand(kIsNotStringMask));
__ b(ne, &convert_argument);
__ mov(argument, r0);
__ IncrementCounter(&Counters::string_ctor_conversions, 1, r3, r4);
__ b(&argument_is_string);
// Invoke the conversion builtin and put the result into r2.
__ bind(&convert_argument);
__ push(function); // Preserve the function.
__ IncrementCounter(&Counters::string_ctor_conversions, 1, r3, r4);
__ EnterInternalFrame();
__ push(r0);
__ InvokeBuiltin(Builtins::TO_STRING, CALL_JS);
__ LeaveInternalFrame();
__ pop(function);
__ mov(argument, r0);
__ b(&argument_is_string);
// Load the empty string into r2, remove the receiver from the
// stack, and jump back to the case where the argument is a string.
__ bind(&no_arguments);
__ LoadRoot(argument, Heap::kEmptyStringRootIndex);
__ Drop(1);
__ b(&argument_is_string);
// At this point the argument is already a string. Call runtime to
// create a string wrapper.
__ bind(&gc_required);
__ IncrementCounter(&Counters::string_ctor_gc_required, 1, r3, r4);
__ EnterInternalFrame();
__ push(argument);
__ CallRuntime(Runtime::kNewStringWrapper, 1);
__ LeaveInternalFrame();
__ Ret();
}

288
deps/v8/src/arm/codegen-arm.cc

@ -6024,6 +6024,68 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
}
class DeferredCountOperation: public DeferredCode {
public:
DeferredCountOperation(Register value,
bool is_increment,
bool is_postfix,
int target_size)
: value_(value),
is_increment_(is_increment),
is_postfix_(is_postfix),
target_size_(target_size) {}
virtual void Generate() {
VirtualFrame copied_frame(*frame_state()->frame());
Label slow;
// Check for smi operand.
__ tst(value_, Operand(kSmiTagMask));
__ b(ne, &slow);
// Revert optimistic increment/decrement.
if (is_increment_) {
__ sub(value_, value_, Operand(Smi::FromInt(1)));
} else {
__ add(value_, value_, Operand(Smi::FromInt(1)));
}
// Slow case: Convert to number. At this point the
// value to be incremented is in the value register..
__ bind(&slow);
// Convert the operand to a number.
copied_frame.EmitPush(value_);
copied_frame.InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
if (is_postfix_) {
// Postfix: store to result (on the stack).
__ str(r0, MemOperand(sp, target_size_ * kPointerSize));
}
copied_frame.EmitPush(r0);
copied_frame.EmitPush(Operand(Smi::FromInt(1)));
if (is_increment_) {
copied_frame.CallRuntime(Runtime::kNumberAdd, 2);
} else {
copied_frame.CallRuntime(Runtime::kNumberSub, 2);
}
__ Move(value_, r0);
copied_frame.MergeTo(frame_state()->frame());
}
private:
Register value_;
bool is_increment_;
bool is_postfix_;
int target_size_;
};
void CodeGenerator::VisitCountOperation(CountOperation* node) {
#ifdef DEBUG
int original_height = frame_->height();
@ -6083,9 +6145,7 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
// the target. It also pushes the current value of the target.
target.GetValue();
JumpTarget slow;
JumpTarget exit;
bool value_is_known_smi = frame_->KnownSmiAt(0);
Register value = frame_->PopToRegister();
// Postfix: Store the old value as the result.
@ -6097,9 +6157,27 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
value = VirtualFrame::scratch0();
}
// Check for smi operand.
__ tst(value, Operand(kSmiTagMask));
slow.Branch(ne);
// We can't use any type information here since the virtual frame from the
// deferred code may have lost information and we can't merge a virtual
// frame with less specific type knowledge to a virtual frame with more
// specific knowledge that has already used that specific knowledge to
// generate code.
frame_->ForgetTypeInfo();
// The constructor here will capture the current virtual frame and use it to
// merge to after the deferred code has run. No virtual frame changes are
// allowed from here until the 'BindExit' below.
DeferredCode* deferred =
new DeferredCountOperation(value,
is_increment,
is_postfix,
target.size());
if (!value_is_known_smi) {
// Check for smi operand.
__ tst(value, Operand(kSmiTagMask));
deferred->Branch(ne);
}
// Perform optimistic increment/decrement.
if (is_increment) {
@ -6108,46 +6186,13 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
__ sub(value, value, Operand(Smi::FromInt(1)), SetCC);
}
// If the increment/decrement didn't overflow, we're done.
exit.Branch(vc);
// Revert optimistic increment/decrement.
if (is_increment) {
__ sub(value, value, Operand(Smi::FromInt(1)));
} else {
__ add(value, value, Operand(Smi::FromInt(1)));
}
// Slow case: Convert to number. At this point the
// value to be incremented is in the value register..
slow.Bind();
// Convert the operand to a number.
frame_->EmitPush(value);
{
VirtualFrame::SpilledScope spilled(frame_);
frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
if (is_postfix) {
// Postfix: store to result (on the stack).
__ str(r0, frame_->ElementAt(target.size()));
}
// If increment/decrement overflows, go to deferred code.
deferred->Branch(vs);
// Compute the new value.
frame_->EmitPush(r0);
frame_->EmitPush(Operand(Smi::FromInt(1)));
if (is_increment) {
frame_->CallRuntime(Runtime::kNumberAdd, 2);
} else {
frame_->CallRuntime(Runtime::kNumberSub, 2);
}
}
deferred->BindExit();
__ Move(value, r0);
// Store the new value in the target if not const.
// At this point the answer is in the value register.
exit.Bind();
frame_->EmitPush(value);
// Set the target with the result, leaving the result on
// top of the stack. Removes the target from the stack if
@ -6537,16 +6582,29 @@ void CodeGenerator::VisitCompareToNull(CompareToNull* node) {
class DeferredReferenceGetNamedValue: public DeferredCode {
public:
explicit DeferredReferenceGetNamedValue(Register receiver,
Handle<String> name)
: receiver_(receiver), name_(name) {
set_comment("[ DeferredReferenceGetNamedValue");
Handle<String> name,
bool is_contextual)
: receiver_(receiver),
name_(name),
is_contextual_(is_contextual),
is_dont_delete_(false) {
set_comment(is_contextual
? "[ DeferredReferenceGetNamedValue (contextual)"
: "[ DeferredReferenceGetNamedValue");
}
virtual void Generate();
void set_is_dont_delete(bool value) {
ASSERT(is_contextual_);
is_dont_delete_ = value;
}
private:
Register receiver_;
Handle<String> name_;
bool is_contextual_;
bool is_dont_delete_;
};
@ -6573,10 +6631,20 @@ void DeferredReferenceGetNamedValue::Generate() {
// The rest of the instructions in the deferred code must be together.
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop(1) instruction to indicate that the
// in-object has been inlined.
__ nop(PROPERTY_ACCESS_INLINED);
RelocInfo::Mode mode = is_contextual_
? RelocInfo::CODE_TARGET_CONTEXT
: RelocInfo::CODE_TARGET;
__ Call(ic, mode);
// We must mark the code just after the call with the correct marker.
MacroAssembler::NopMarkerTypes code_marker;
if (is_contextual_) {
code_marker = is_dont_delete_
? MacroAssembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE
: MacroAssembler::PROPERTY_ACCESS_INLINED_CONTEXT;
} else {
code_marker = MacroAssembler::PROPERTY_ACCESS_INLINED;
}
__ MarkCode(code_marker);
// At this point the answer is in r0. We move it to the expected register
// if necessary.
@ -6640,7 +6708,7 @@ void DeferredReferenceGetKeyedValue::Generate() {
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
// keyed load has been inlined.
__ nop(PROPERTY_ACCESS_INLINED);
__ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED);
// Now go back to the frame that we entered with. This will not overwrite
// the receiver or key registers since they were not in use when we came
@ -6697,7 +6765,7 @@ void DeferredReferenceSetKeyedValue::Generate() {
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
// keyed store has been inlined.
__ nop(PROPERTY_ACCESS_INLINED);
__ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED);
// Block the constant pool for one more instruction after leaving this
// constant pool block scope to include the branch instruction ending the
@ -6745,7 +6813,7 @@ void DeferredReferenceSetNamedValue::Generate() {
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
// named store has been inlined.
__ nop(PROPERTY_ACCESS_INLINED);
__ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED);
// Go back to the frame we entered with. The instructions
// generated by this merge are skipped over by the inline store
@ -6763,7 +6831,14 @@ void DeferredReferenceSetNamedValue::Generate() {
// Consumes the top of stack (the receiver) and pushes the result instead.
void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
bool contextual_load_in_builtin =
is_contextual &&
(Bootstrapper::IsActive() ||
(!info_->closure().is_null() && info_->closure()->IsBuiltin()));
if (scope()->is_global_scope() ||
loop_nesting() == 0 ||
contextual_load_in_builtin) {
Comment cmnt(masm(), "[ Load from named Property");
// Setup the name register and call load IC.
frame_->CallLoadIC(name,
@ -6773,12 +6848,19 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
frame_->EmitPush(r0); // Push answer.
} else {
// Inline the in-object property case.
Comment cmnt(masm(), "[ Inlined named property load");
Comment cmnt(masm(), is_contextual
? "[ Inlined contextual property load"
: "[ Inlined named property load");
// Counter will be decremented in the deferred code. Placed here to avoid
// having it in the instruction stream below where patching will occur.
__ IncrementCounter(&Counters::named_load_inline, 1,
frame_->scratch0(), frame_->scratch1());
if (is_contextual) {
__ IncrementCounter(&Counters::named_load_global_inline, 1,
frame_->scratch0(), frame_->scratch1());
} else {
__ IncrementCounter(&Counters::named_load_inline, 1,
frame_->scratch0(), frame_->scratch1());
}
// The following instructions are the inlined load of an in-object property.
// Parts of this code is patched, so the exact instructions generated needs
@ -6789,19 +6871,57 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
Register receiver = frame_->PopToRegister();
DeferredReferenceGetNamedValue* deferred =
new DeferredReferenceGetNamedValue(receiver, name);
new DeferredReferenceGetNamedValue(receiver, name, is_contextual);
bool is_dont_delete = false;
if (is_contextual) {
if (!info_->closure().is_null()) {
// When doing lazy compilation we can check if the global cell
// already exists and use its "don't delete" status as a hint.
AssertNoAllocation no_gc;
v8::internal::GlobalObject* global_object =
info_->closure()->context()->global();
LookupResult lookup;
global_object->LocalLookupRealNamedProperty(*name, &lookup);
if (lookup.IsProperty() && lookup.type() == NORMAL) {
ASSERT(lookup.holder() == global_object);
ASSERT(global_object->property_dictionary()->ValueAt(
lookup.GetDictionaryEntry())->IsJSGlobalPropertyCell());
is_dont_delete = lookup.IsDontDelete();
}
}
if (is_dont_delete) {
__ IncrementCounter(&Counters::dont_delete_hint_hit, 1,
frame_->scratch0(), frame_->scratch1());
}
}
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
if (!is_contextual) {
// Check that the receiver is a heap object.
__ tst(receiver, Operand(kSmiTagMask));
deferred->Branch(eq);
}
// Check for the_hole_value if necessary.
// Below we rely on the number of instructions generated, and we can't
// cope with the Check macro which does not generate a fixed number of
// instructions.
Label skip, check_the_hole, cont;
if (FLAG_debug_code && is_contextual && is_dont_delete) {
__ b(&skip);
__ bind(&check_the_hole);
__ Check(ne, "DontDelete cells can't contain the hole");
__ b(&cont);
__ bind(&skip);
}
#ifdef DEBUG
int kInlinedNamedLoadInstructions = 7;
Label check_inlined_codesize;
masm_->bind(&check_inlined_codesize);
int InlinedNamedLoadInstructions = 5;
Label check_inlined_codesize;
masm_->bind(&check_inlined_codesize);
#endif
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
// Check that the receiver is a heap object.
__ tst(receiver, Operand(kSmiTagMask));
deferred->Branch(eq);
Register scratch = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
@ -6812,12 +6932,42 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
__ cmp(scratch, scratch2);
deferred->Branch(ne);
// Initially use an invalid index. The index will be patched by the
// inline cache code.
__ ldr(receiver, MemOperand(receiver, 0));
if (is_contextual) {
#ifdef DEBUG
InlinedNamedLoadInstructions += 1;
#endif
// Load the (initially invalid) cell and get its value.
masm()->mov(receiver, Operand(Factory::null_value()));
__ ldr(receiver,
FieldMemOperand(receiver, JSGlobalPropertyCell::kValueOffset));
deferred->set_is_dont_delete(is_dont_delete);
if (!is_dont_delete) {
#ifdef DEBUG
InlinedNamedLoadInstructions += 3;
#endif
__ cmp(receiver, Operand(Factory::the_hole_value()));
deferred->Branch(eq);
} else if (FLAG_debug_code) {
#ifdef DEBUG
InlinedNamedLoadInstructions += 3;
#endif
__ cmp(receiver, Operand(Factory::the_hole_value()));
__ b(&check_the_hole, eq);
__ bind(&cont);
}
} else {
// Initially use an invalid index. The index will be patched by the
// inline cache code.
__ ldr(receiver, MemOperand(receiver, 0));
}
// Make sure that the expected number of instructions are generated.
ASSERT_EQ(kInlinedNamedLoadInstructions,
// If the code before is updated, the offsets in ic-arm.cc
// LoadIC::PatchInlinedContextualLoad and PatchInlinedLoad need
// to be updated.
ASSERT_EQ(InlinedNamedLoadInstructions,
masm_->InstructionsGeneratedSince(&check_inlined_codesize));
}

8
deps/v8/src/arm/codegen-arm.h

@ -194,14 +194,6 @@ enum ArgumentsAllocationMode {
};
// Different nop operations are used by the code generator to detect certain
// states of the generated code.
enum NopMarkerTypes {
NON_MARKING_NOP = 0,
PROPERTY_ACCESS_INLINED
};
// -------------------------------------------------------------------------
// CodeGenerator

2
deps/v8/src/arm/debug-arm.cc

@ -279,7 +279,7 @@ void Debug::GenerateSlot(MacroAssembler* masm) {
__ bind(&check_codesize);
__ RecordDebugBreakSlot();
for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
__ nop(2);
__ nop(MacroAssembler::DEBUG_BREAK_NOP);
}
ASSERT_EQ(Assembler::kDebugBreakSlotInstructions,
masm->InstructionsGeneratedSince(&check_codesize));

79
deps/v8/src/arm/ic-arm.cc

@ -904,9 +904,9 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
__ TailCallExternalReference(ref, 2, 1);
}
static inline bool IsInlinedICSite(Address address,
Address* inline_end_address) {
// Returns the code marker, or the 0 if the code is not marked.
static inline int InlinedICSiteMarker(Address address,
Address* inline_end_address) {
// If the instruction after the call site is not the pseudo instruction nop1
// then this is not related to an inlined in-object property load. The nop1
// instruction is located just after the call to the IC in the deferred code
@ -914,9 +914,11 @@ static inline bool IsInlinedICSite(Address address,
// a branch instruction for jumping back from the deferred code.
Address address_after_call = address + Assembler::kCallTargetAddressOffset;
Instr instr_after_call = Assembler::instr_at(address_after_call);
if (!Assembler::IsNop(instr_after_call, PROPERTY_ACCESS_INLINED)) {
return false;
}
int code_marker = MacroAssembler::GetCodeMarker(instr_after_call);
// A negative result means the code is not marked.
if (code_marker <= 0) return 0;
Address address_after_nop = address_after_call + Assembler::kInstrSize;
Instr instr_after_nop = Assembler::instr_at(address_after_nop);
// There may be some reg-reg move and frame merging code to skip over before
@ -933,7 +935,7 @@ static inline bool IsInlinedICSite(Address address,
ASSERT(b_offset < 0); // Jumping back from deferred code.
*inline_end_address = address_after_nop + b_offset;
return true;
return code_marker;
}
@ -941,7 +943,10 @@ bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
// Find the end of the inlined code for handling the load if this is an
// inlined IC call site.
Address inline_end_address;
if (!IsInlinedICSite(address, &inline_end_address)) return false;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
}
// Patch the offset of the property load instruction (ldr r0, [r1, #+XXX]).
// The immediate must be representable in 12 bits.
@ -959,8 +964,12 @@ bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
CPU::FlushICache(ldr_property_instr_address, 1 * Assembler::kInstrSize);
// Patch the map check.
// For PROPERTY_ACCESS_INLINED, the load map instruction is generated
// 4 instructions before the end of the inlined code.
// See codgen-arm.cc CodeGenerator::EmitNamedLoad.
int ldr_map_offset = -4;
Address ldr_map_instr_address =
inline_end_address - 4 * Assembler::kInstrSize;
inline_end_address + ldr_map_offset * Assembler::kInstrSize;
Assembler::set_target_address_at(ldr_map_instr_address,
reinterpret_cast<Address>(map));
return true;
@ -971,8 +980,41 @@ bool LoadIC::PatchInlinedContextualLoad(Address address,
Object* map,
Object* cell,
bool is_dont_delete) {
// TODO(<bug#>): implement this.
return false;
// Find the end of the inlined code for handling the contextual load if
// this is inlined IC call site.
Address inline_end_address;
int marker = InlinedICSiteMarker(address, &inline_end_address);
if (!((marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT) ||
(marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE))) {
return false;
}
// On ARM we don't rely on the is_dont_delete argument as the hint is already
// embedded in the code marker.
bool marker_is_dont_delete =
marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE;
// These are the offsets from the end of the inlined code.
// See codgen-arm.cc CodeGenerator::EmitNamedLoad.
int ldr_map_offset = marker_is_dont_delete ? -5: -8;
int ldr_cell_offset = marker_is_dont_delete ? -2: -5;
if (FLAG_debug_code && marker_is_dont_delete) {
// Three extra instructions were generated to check for the_hole_value.
ldr_map_offset -= 3;
ldr_cell_offset -= 3;
}
Address ldr_map_instr_address =
inline_end_address + ldr_map_offset * Assembler::kInstrSize;
Address ldr_cell_instr_address =
inline_end_address + ldr_cell_offset * Assembler::kInstrSize;
// Patch the map check.
Assembler::set_target_address_at(ldr_map_instr_address,
reinterpret_cast<Address>(map));
// Patch the cell address.
Assembler::set_target_address_at(ldr_cell_instr_address,
reinterpret_cast<Address>(cell));
return true;
}
@ -980,7 +1022,10 @@ bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
// Find the end of the inlined code for the store if there is an
// inlined version of the store.
Address inline_end_address;
if (!IsInlinedICSite(address, &inline_end_address)) return false;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
}
// Compute the address of the map load instruction.
Address ldr_map_instr_address =
@ -1025,7 +1070,10 @@ bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
Address inline_end_address;
if (!IsInlinedICSite(address, &inline_end_address)) return false;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
}
// Patch the map check.
Address ldr_map_instr_address =
@ -1042,7 +1090,10 @@ bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
// Find the end of the inlined code for handling the store if this is an
// inlined IC call site.
Address inline_end_address;
if (!IsInlinedICSite(address, &inline_end_address)) return false;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
}
// Patch the map check.
Address ldr_map_instr_address =

27
deps/v8/src/arm/macro-assembler-arm.cc

@ -1693,6 +1693,33 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
}
void MacroAssembler::LoadGlobalFunction(int index, Register function) {
// Load the global or builtins object from the current context.
ldr(function, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
// Load the global context from the global or builtins object.
ldr(function, FieldMemOperand(function,
GlobalObject::kGlobalContextOffset));
// Load the function from the global context.
ldr(function, MemOperand(function, Context::SlotOffset(index)));
}
void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
Register map,
Register scratch) {
// Load the initial map. The global functions all have initial maps.
ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
if (FLAG_debug_code) {
Label ok, fail;
CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, false);
b(&ok);
bind(&fail);
Abort("Global functions must have initial map");
bind(&ok);
}
}
void MacroAssembler::JumpIfNotBothSmi(Register reg1,
Register reg2,
Label* on_not_both_smi) {

42
deps/v8/src/arm/macro-assembler-arm.h

@ -264,6 +264,14 @@ class MacroAssembler: public Assembler {
void LoadContext(Register dst, int context_chain_length);
void LoadGlobalFunction(int index, Register function);
// Load the initial map from the global function. The registers
// function and map can be the same, function is then overwritten.
void LoadGlobalFunctionInitialMap(Register function,
Register map,
Register scratch);
// ---------------------------------------------------------------------------
// JavaScript invokes
@ -319,6 +327,40 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* miss);
inline void MarkCode(NopMarkerTypes type) {
nop(type);
}
// Check if the given instruction is a 'type' marker.
// ie. check if is is a mov r<type>, r<type> (referenced as nop(type))
// These instructions are generated to mark special location in the code,
// like some special IC code.
static inline bool IsMarkedCode(Instr instr, int type) {
ASSERT((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
return IsNop(instr, type);
}
static inline int GetCodeMarker(Instr instr) {
int dst_reg_offset = 12;
int dst_mask = 0xf << dst_reg_offset;
int src_mask = 0xf;
int dst_reg = (instr & dst_mask) >> dst_reg_offset;
int src_reg = instr & src_mask;
uint32_t non_register_mask = ~(dst_mask | src_mask);
uint32_t mov_mask = al | 13 << 21;
// Return <n> if we have a mov rn rn, else return -1.
int type = ((instr & non_register_mask) == mov_mask) &&
(dst_reg == src_reg) &&
(FIRST_IC_MARKER <= dst_reg) && (dst_reg < LAST_CODE_MARKER)
? src_reg
: -1;
ASSERT((type == -1) ||
((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
return type;
}
// ---------------------------------------------------------------------------
// Allocation support

7
deps/v8/src/arm/stub-cache-arm.cc

@ -2902,8 +2902,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
}
MaybeObject* ConstructStubCompiler::CompileConstructStub(
SharedFunctionInfo* shared) {
MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
// ----------- S t a t e -------------
// -- r0 : argc
// -- r1 : constructor
@ -2987,6 +2986,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(
// r7: undefined
// Fill the initialized properties with a constant value or a passed argument
// depending on the this.x = ...; assignment in the function.
SharedFunctionInfo* shared = function->shared();
for (int i = 0; i < shared->this_property_assignments_count(); i++) {
if (shared->IsThisPropertyAssignmentArgument(i)) {
Label not_passed, next;
@ -3011,8 +3011,9 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(
}
// Fill the unused in-object property fields with undefined.
ASSERT(function->has_initial_map());
for (int i = shared->this_property_assignments_count();
i < shared->CalculateInObjectProperties();
i < function->initial_map()->inobject_properties();
i++) {
__ str(r7, MemOperand(r5, kPointerSize, PostIndex));
}

1
deps/v8/src/checks.cc

@ -107,3 +107,4 @@ namespace v8 { namespace internal {
intptr_t HeapObjectTagMask() { return kHeapObjectTagMask; }
} } // namespace v8::internal

34
deps/v8/src/checks.h

@ -31,7 +31,6 @@
#include <string.h>
extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
void API_Fatal(const char* location, const char* format, ...);
// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
// development, but they should not be relied on in the final product.
@ -222,28 +221,6 @@ static inline void CheckNonEqualsHelper(const char* file,
}
namespace v8 {
class Value;
template <class T> class Handle;
}
void CheckNonEqualsHelper(const char* file,
int line,
const char* unexpected_source,
v8::Handle<v8::Value> unexpected,
const char* value_source,
v8::Handle<v8::Value> value);
void CheckEqualsHelper(const char* file,
int line,
const char* expected_source,
v8::Handle<v8::Value> expected,
const char* value_source,
v8::Handle<v8::Value> value);
#define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
#expected, expected, #value, value)
@ -307,17 +284,6 @@ bool EnableSlowAsserts();
// and release compilation modes behaviour.
#define STATIC_ASSERT(test) STATIC_CHECK(test)
namespace v8 { namespace internal {
intptr_t HeapObjectTagMask();
} } // namespace v8::internal
#define ASSERT_TAG_ALIGNED(address) \
ASSERT((reinterpret_cast<intptr_t>(address) & HeapObjectTagMask()) == 0)
#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & HeapObjectTagMask()) == 0)
#define ASSERT_NOT_NULL(p) ASSERT_NE(NULL, p)
#endif // V8_CHECKS_H_

6
deps/v8/src/conversions.cc

@ -448,12 +448,12 @@ static double InternalStringToDouble(Iterator current,
bool sign = false;
if (*current == '+') {
// Ignore leading sign; skip following spaces.
// Ignore leading sign.
++current;
if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
if (current == end) return JUNK_STRING_VALUE;
} else if (*current == '-') {
++current;
if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
if (current == end) return JUNK_STRING_VALUE;
sign = true;
}

2
deps/v8/src/dateparser-inl.h

@ -59,7 +59,7 @@ bool DateParser::Parse(Vector<Char> str, FixedArray* out) {
} else if (in.Skip('.') && time.IsExpecting(n)) {
time.Add(n);
if (!in.IsAsciiDigit()) return false;
int n = in.ReadUnsignedNumber();
int n = in.ReadMilliseconds();
time.AddFinal(n);
} else if (tz.IsExpecting(n)) {
tz.SetAbsoluteMinute(n);

12
deps/v8/src/dateparser.h

@ -87,6 +87,18 @@ class DateParser : public AllStatic {
return n;
}
// Read a string of digits, take the first three or fewer as an unsigned
// number of milliseconds, and ignore any digits after the first three.
int ReadMilliseconds() {
has_read_number_ = true;
int n = 0;
int power;
for (power = 100; IsAsciiDigit(); Next(), power = power / 10) {
n = n + power * (ch_ - '0');
}
return n;
}
// Read a word (sequence of chars. >= 'A'), fill the given buffer with a
// lower-case prefix, and pad any remainder of the buffer with zeroes.
// Return word length.

2
deps/v8/src/handles.cc

@ -143,7 +143,7 @@ Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
void SetExpectedNofProperties(Handle<JSFunction> func, int nof) {
// If objects constructed from this function exist then changing
// 'estimated_nof_properties' is dangerous since the previois value might
// 'estimated_nof_properties' is dangerous since the previous value might
// have been compiled into the fast construct stub. More over, the inobject
// slack tracking logic might have adjusted the previous value, so even
// passing the same value is risky.

8
deps/v8/src/hashmap.cc

@ -25,7 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "v8.h"
#include "../include/v8stdint.h"
#include "globals.h"
#include "checks.h"
#include "utils.h"
#include "allocation.h"
#include "hashmap.h"
@ -195,7 +199,7 @@ void HashMap::Initialize(uint32_t capacity) {
ASSERT(IsPowerOf2(capacity));
map_ = reinterpret_cast<Entry*>(allocator_->New(capacity * sizeof(Entry)));
if (map_ == NULL) {
V8::FatalProcessOutOfMemory("HashMap::Initialize");
v8::internal::FatalProcessOutOfMemory("HashMap::Initialize");
return;
}
capacity_ = capacity;

10
deps/v8/src/heap-profiler.cc

@ -69,7 +69,8 @@ class Clusterizer : public AllStatic {
JSObjectsCluster Clusterizer::Clusterize(HeapObject* obj, bool fine_grain) {
if (obj->IsJSObject()) {
JSObject* js_obj = JSObject::cast(obj);
String* constructor = JSObject::cast(js_obj)->constructor_name();
String* constructor = GetConstructorNameForHeapProfile(
JSObject::cast(js_obj));
// Differentiate Object and Array instances.
if (fine_grain && (constructor == Heap::Object_symbol() ||
constructor == Heap::Array_symbol())) {
@ -714,7 +715,7 @@ static void StackWeakReferenceCallback(Persistent<Value> object,
static void PrintProducerStackTrace(Object* obj, void* trace) {
if (!obj->IsJSObject()) return;
String* constructor = JSObject::cast(obj)->constructor_name();
String* constructor = GetConstructorNameForHeapProfile(JSObject::cast(obj));
SmartPointer<char> s_name(
constructor->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL));
LOG(HeapSampleJSProducerEvent(GetConstructorName(*s_name),
@ -886,7 +887,8 @@ static JSObjectsCluster HeapObjectAsCluster(HeapObject* object) {
return JSObjectsCluster(String::cast(object));
} else {
JSObject* js_obj = JSObject::cast(object);
String* constructor = JSObject::cast(js_obj)->constructor_name();
String* constructor = GetConstructorNameForHeapProfile(
JSObject::cast(js_obj));
return JSObjectsCluster(constructor, object);
}
}
@ -1064,6 +1066,8 @@ void AggregatedHeapSnapshotGenerator::FillHeapSnapshot(HeapSnapshot* snapshot) {
// Fill up references.
IterateRetainers<AllocatingRetainersIterator>(&entries_map);
snapshot->SetDominatorsToSelf();
}

8
deps/v8/src/ia32/macro-assembler-ia32.cc

@ -537,7 +537,6 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
void MacroAssembler::LoadAllocationTopHelper(Register result,
Register result_end,
Register scratch,
AllocationFlags flags) {
ExternalReference new_space_allocation_top =
@ -559,7 +558,6 @@ void MacroAssembler::LoadAllocationTopHelper(Register result,
if (scratch.is(no_reg)) {
mov(result, Operand::StaticVariable(new_space_allocation_top));
} else {
ASSERT(!scratch.is(result_end));
mov(Operand(scratch), Immediate(new_space_allocation_top));
mov(result, Operand(scratch, 0));
}
@ -608,7 +606,7 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
ASSERT(!result.is(result_end));
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
LoadAllocationTopHelper(result, scratch, flags);
Register top_reg = result_end.is_valid() ? result_end : result;
@ -664,7 +662,7 @@ void MacroAssembler::AllocateInNewSpace(int header_size,
ASSERT(!result.is(result_end));
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
LoadAllocationTopHelper(result, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
@ -705,7 +703,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
ASSERT(!result.is(result_end));
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
LoadAllocationTopHelper(result, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =

1
deps/v8/src/ia32/macro-assembler-ia32.h

@ -631,7 +631,6 @@ class MacroAssembler: public Assembler {
// Allocation support helpers.
void LoadAllocationTopHelper(Register result,
Register result_end,
Register scratch,
AllocationFlags flags);
void UpdateAllocationTopHelper(Register result_end, Register scratch);

7
deps/v8/src/ia32/stub-cache-ia32.cc

@ -3021,8 +3021,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
// Specialized stub for constructing objects from functions which only have only
// simple assignments of the form this.x = ...; in their body.
MaybeObject* ConstructStubCompiler::CompileConstructStub(
SharedFunctionInfo* shared) {
MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
// ----------- S t a t e -------------
// -- eax : argc
// -- edi : constructor
@ -3098,6 +3097,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(
// edi: undefined
// Fill the initialized properties with a constant value or a passed argument
// depending on the this.x = ...; assignment in the function.
SharedFunctionInfo* shared = function->shared();
for (int i = 0; i < shared->this_property_assignments_count(); i++) {
if (shared->IsThisPropertyAssignmentArgument(i)) {
// Check if the argument assigned to the property is actually passed.
@ -3125,8 +3125,9 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(
}
// Fill the unused in-object property fields with undefined.
ASSERT(function->has_initial_map());
for (int i = shared->this_property_assignments_count();
i < shared->CalculateInObjectProperties();
i < function->initial_map()->inobject_properties();
i++) {
__ mov(Operand(edx, i * kPointerSize), edi);
}

11
deps/v8/src/log.cc

@ -194,11 +194,6 @@ class Ticker: public Sampler {
~Ticker() { if (IsActive()) Stop(); }
virtual void SampleStack(TickSample* sample) {
ASSERT(IsSynchronous());
StackTracer::Trace(sample);
}
virtual void Tick(TickSample* sample) {
if (profiler_) profiler_->Insert(sample);
if (window_) window_->AddState(sample->state);
@ -224,6 +219,12 @@ class Ticker: public Sampler {
if (!window_ && IsActive()) Stop();
}
protected:
virtual void DoSampleStack(TickSample* sample) {
ASSERT(IsSynchronous());
StackTracer::Trace(sample);
}
private:
SlidingStateWindow* window_;
Profiler* profiler_;

3
deps/v8/src/objects.cc

@ -1166,9 +1166,6 @@ String* JSObject::class_name() {
String* JSObject::constructor_name() {
if (IsJSFunction()) {
return Heap::closure_symbol();
}
if (map()->constructor()->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(map()->constructor());
String* name = String::cast(constructor->shared()->name());

193
deps/v8/src/parser.cc

@ -356,65 +356,6 @@ Handle<String> Parser::LookupCachedSymbol(int symbol_id,
}
Vector<unsigned> PartialParserRecorder::ExtractData() {
int function_size = function_store_.size();
int total_size = ScriptDataImpl::kHeaderSize + function_size;
Vector<unsigned> data = Vector<unsigned>::New(total_size);
preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
memcpy(data.start(), preamble_, sizeof(preamble_));
int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
if (function_size > 0) {
function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
symbol_start));
}
return data;
}
void CompleteParserRecorder::LogSymbol(int start, Vector<const char> literal) {
if (!is_recording_) return;
int hash = vector_hash(literal);
HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
if (id == 0) {
// Put (symbol_id_ + 1) into entry and increment it.
id = ++symbol_id_;
entry->value = reinterpret_cast<void*>(id);
Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
entry->key = &symbol[0];
}
WriteNumber(id - 1);
}
Vector<unsigned> CompleteParserRecorder::ExtractData() {
int function_size = function_store_.size();
// Add terminator to symbols, then pad to unsigned size.
int symbol_size = symbol_store_.size();
int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned));
symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator);
symbol_size += padding;
int total_size = ScriptDataImpl::kHeaderSize + function_size
+ (symbol_size / sizeof(unsigned));
Vector<unsigned> data = Vector<unsigned>::New(total_size);
preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_;
memcpy(data.start(), preamble_, sizeof(preamble_));
int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
if (function_size > 0) {
function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
symbol_start));
}
if (!has_error()) {
symbol_store_.WriteTo(
Vector<byte>::cast(data.SubVector(symbol_start, total_size)));
}
return data;
}
FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
// The current pre-data entry must be a FunctionEntry with the given
// start position.
@ -437,92 +378,52 @@ int ScriptDataImpl::GetSymbolIdentifier() {
bool ScriptDataImpl::SanityCheck() {
// Check that the header data is valid and doesn't specify
// point to positions outside the store.
if (store_.length() < ScriptDataImpl::kHeaderSize) return false;
if (magic() != ScriptDataImpl::kMagicNumber) return false;
if (version() != ScriptDataImpl::kCurrentVersion) return false;
if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
if (magic() != PreparseDataConstants::kMagicNumber) return false;
if (version() != PreparseDataConstants::kCurrentVersion) return false;
if (has_error()) {
// Extra sane sanity check for error message encoding.
if (store_.length() <= kHeaderSize + kMessageTextPos) return false;
if (Read(kMessageStartPos) > Read(kMessageEndPos)) return false;
unsigned arg_count = Read(kMessageArgCountPos);
int pos = kMessageTextPos;
if (store_.length() <= PreparseDataConstants::kHeaderSize
+ PreparseDataConstants::kMessageTextPos) {
return false;
}
if (Read(PreparseDataConstants::kMessageStartPos) >
Read(PreparseDataConstants::kMessageEndPos)) {
return false;
}
unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
int pos = PreparseDataConstants::kMessageTextPos;
for (unsigned int i = 0; i <= arg_count; i++) {
if (store_.length() <= kHeaderSize + pos) return false;
if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
return false;
}
int length = static_cast<int>(Read(pos));
if (length < 0) return false;
pos += 1 + length;
}
if (store_.length() < kHeaderSize + pos) return false;
if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
return false;
}
return true;
}
// Check that the space allocated for function entries is sane.
int functions_size =
static_cast<int>(store_[ScriptDataImpl::kFunctionsSizeOffset]);
static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
if (functions_size < 0) return false;
if (functions_size % FunctionEntry::kSize != 0) return false;
// Check that the count of symbols is non-negative.
int symbol_count =
static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]);
static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
if (symbol_count < 0) return false;
// Check that the total size has room for header and function entries.
int minimum_size =
ScriptDataImpl::kHeaderSize + functions_size;
PreparseDataConstants::kHeaderSize + functions_size;
if (store_.length() < minimum_size) return false;
return true;
}
PartialParserRecorder::PartialParserRecorder()
: function_store_(0),
is_recording_(true),
pause_count_(0) {
preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
preamble_[ScriptDataImpl::kHasErrorOffset] = false;
preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0;
preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
preamble_[ScriptDataImpl::kSizeOffset] = 0;
ASSERT_EQ(6, ScriptDataImpl::kHeaderSize);
#ifdef DEBUG
prev_start_ = -1;
#endif
}
CompleteParserRecorder::CompleteParserRecorder()
: PartialParserRecorder(),
symbol_store_(0),
symbol_entries_(0),
symbol_table_(vector_compare),
symbol_id_(0) {
}
void PartialParserRecorder::WriteString(Vector<const char> str) {
function_store_.Add(str.length());
for (int i = 0; i < str.length(); i++) {
function_store_.Add(str[i]);
}
}
void CompleteParserRecorder::WriteNumber(int number) {
ASSERT(number >= 0);
int mask = (1 << 28) - 1;
for (int i = 28; i > 0; i -= 7) {
if (number > mask) {
symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u);
number &= mask;
}
mask >>= 7;
}
symbol_store_.Add(static_cast<byte>(number));
}
const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
int length = start[0];
char* result = NewArray<char>(length + 1);
@ -534,47 +435,26 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
return result;
}
void PartialParserRecorder::LogMessage(Scanner::Location loc,
const char* message,
Vector<const char*> args) {
if (has_error()) return;
preamble_[ScriptDataImpl::kHasErrorOffset] = true;
function_store_.Reset();
STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0);
function_store_.Add(loc.beg_pos);
STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1);
function_store_.Add(loc.end_pos);
STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2);
function_store_.Add(args.length());
STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3);
WriteString(CStrVector(message));
for (int i = 0; i < args.length(); i++) {
WriteString(CStrVector(args[i]));
}
is_recording_ = false;
}
Scanner::Location ScriptDataImpl::MessageLocation() {
int beg_pos = Read(kMessageStartPos);
int end_pos = Read(kMessageEndPos);
int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
int end_pos = Read(PreparseDataConstants::kMessageEndPos);
return Scanner::Location(beg_pos, end_pos);
}
const char* ScriptDataImpl::BuildMessage() {
unsigned* start = ReadAddress(kMessageTextPos);
unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
return ReadString(start, NULL);
}
Vector<const char*> ScriptDataImpl::BuildArgs() {
int arg_count = Read(kMessageArgCountPos);
int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
const char** array = NewArray<const char*>(arg_count);
// Position after text found by skipping past length field and
// length field content words.
int pos = kMessageTextPos + 1 + Read(kMessageTextPos);
int pos = PreparseDataConstants::kMessageTextPos + 1
+ Read(PreparseDataConstants::kMessageTextPos);
for (int i = 0; i < arg_count; i++) {
int count = 0;
array[i] = ReadString(ReadAddress(pos), &count);
@ -585,12 +465,12 @@ Vector<const char*> ScriptDataImpl::BuildArgs() {
unsigned ScriptDataImpl::Read(int position) {
return store_[ScriptDataImpl::kHeaderSize + position];
return store_[PreparseDataConstants::kHeaderSize + position];
}
unsigned* ScriptDataImpl::ReadAddress(int position) {
return &store_[ScriptDataImpl::kHeaderSize + position];
return &store_[PreparseDataConstants::kHeaderSize + position];
}
@ -4601,9 +4481,10 @@ bool ScriptDataImpl::HasError() {
void ScriptDataImpl::Initialize() {
// Prepares state for use.
if (store_.length() >= kHeaderSize) {
function_index_ = kHeaderSize;
int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset];
if (store_.length() >= PreparseDataConstants::kHeaderSize) {
function_index_ = PreparseDataConstants::kHeaderSize;
int symbol_data_offset = PreparseDataConstants::kHeaderSize
+ store_[PreparseDataConstants::kFunctionsSizeOffset];
if (store_.length() > symbol_data_offset) {
symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
} else {
@ -4625,7 +4506,7 @@ int ScriptDataImpl::ReadNumber(byte** source) {
byte* data = *source;
if (data >= symbol_data_end_) return -1;
byte input = *data;
if (input == kNumberTerminator) {
if (input == PreparseDataConstants::kNumberTerminator) {
// End of stream marker.
return -1;
}
@ -4646,11 +4527,11 @@ int ScriptDataImpl::ReadNumber(byte** source) {
static ScriptDataImpl* DoPreParse(Handle<String> source,
unibrow::CharacterStream* stream,
bool allow_lazy,
PartialParserRecorder* recorder,
ParserRecorder* recorder,
int literal_flags) {
V8JavaScriptScanner scanner;
scanner.Initialize(source, stream, literal_flags);
preparser::PreParser<JavaScriptScanner, PartialParserRecorder> preparser;
preparser::PreParser preparser;
if (!preparser.PreParseProgram(&scanner, recorder, allow_lazy)) {
Top::StackOverflow();
return NULL;

151
deps/v8/src/parser.h

@ -32,6 +32,7 @@
#include "ast.h"
#include "scanner.h"
#include "scopes.h"
#include "preparse-data.h"
namespace v8 {
namespace internal {
@ -123,32 +124,15 @@ class ScriptDataImpl : public ScriptData {
Vector<const char*> BuildArgs();
int symbol_count() {
return (store_.length() > kHeaderSize) ? store_[kSymbolCountOffset] : 0;
return (store_.length() > PreparseDataConstants::kHeaderSize)
? store_[PreparseDataConstants::kSymbolCountOffset]
: 0;
}
// The following functions should only be called if SanityCheck has
// returned true.
bool has_error() { return store_[kHasErrorOffset]; }
unsigned magic() { return store_[kMagicOffset]; }
unsigned version() { return store_[kVersionOffset]; }
static const unsigned kMagicNumber = 0xBadDead;
static const unsigned kCurrentVersion = 5;
static const int kMagicOffset = 0;
static const int kVersionOffset = 1;
static const int kHasErrorOffset = 2;
static const int kFunctionsSizeOffset = 3;
static const int kSymbolCountOffset = 4;
static const int kSizeOffset = 5;
static const int kHeaderSize = 6;
// If encoding a message, the following positions are fixed.
static const int kMessageStartPos = 0;
static const int kMessageEndPos = 1;
static const int kMessageArgCountPos = 2;
static const int kMessageTextPos = 3;
static const byte kNumberTerminator = 0x80u;
bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
private:
Vector<unsigned> store_;
@ -177,127 +161,6 @@ class ScriptDataImpl : public ScriptData {
};
// Record only functions.
class PartialParserRecorder {
public:
PartialParserRecorder();
virtual ~PartialParserRecorder() {}
void LogFunction(int start, int end, int literals, int properties) {
function_store_.Add(start);
function_store_.Add(end);
function_store_.Add(literals);
function_store_.Add(properties);
}
virtual void LogSymbol(int start, const char* symbol, int length) { }
// Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector
// representing the error only.
void LogMessage(int start,
int end,
const char* message,
const char* argument_opt) {
Scanner::Location location(start, end);
Vector<const char*> arguments;
if (argument_opt != NULL) {
arguments = Vector<const char*>(&argument_opt, 1);
}
this->LogMessage(location, message, arguments);
}
int function_position() { return function_store_.size(); }
void LogMessage(Scanner::Location loc,
const char* message,
Vector<const char*> args);
virtual Vector<unsigned> ExtractData();
void PauseRecording() {
pause_count_++;
is_recording_ = false;
}
void ResumeRecording() {
ASSERT(pause_count_ > 0);
if (--pause_count_ == 0) is_recording_ = !has_error();
}
int symbol_position() { return 0; }
int symbol_ids() { return 0; }
protected:
bool has_error() {
return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
}
bool is_recording() {
return is_recording_;
}
void WriteString(Vector<const char> str);
Collector<unsigned> function_store_;
unsigned preamble_[ScriptDataImpl::kHeaderSize];
bool is_recording_;
int pause_count_;
#ifdef DEBUG
int prev_start_;
#endif
};
// Record both functions and symbols.
class CompleteParserRecorder: public PartialParserRecorder {
public:
CompleteParserRecorder();
virtual ~CompleteParserRecorder() { }
void LogSymbol(int start, Vector<const char> literal);
virtual void LogSymbol(int start, const char* symbol, int length) {
LogSymbol(start, Vector<const char>(symbol, length));
}
virtual Vector<unsigned> ExtractData();
int symbol_position() { return symbol_store_.size(); }
int symbol_ids() { return symbol_id_; }
private:
static int vector_hash(Vector<const char> string) {
int hash = 0;
for (int i = 0; i < string.length(); i++) {
int c = string[i];
hash += c;
hash += (hash << 10);
hash ^= (hash >> 6);
}
return hash;
}
static bool vector_compare(void* a, void* b) {
Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a);
Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b);
int length = string1->length();
if (string2->length() != length) return false;
return memcmp(string1->start(), string2->start(), length) == 0;
}
// Write a non-negative number to the symbol store.
void WriteNumber(int number);
Collector<byte> symbol_store_;
Collector<Vector<const char> > symbol_entries_;
HashMap symbol_table_;
int symbol_id_;
};
class ParserApi {
public:
// Parses the source code represented by the compilation info and sets its

3
deps/v8/src/platform-freebsd.cc

@ -620,7 +620,8 @@ Sampler::Sampler(int interval, bool profiling)
: interval_(interval),
profiling_(profiling),
synchronous_(profiling),
active_(false) {
active_(false),
samples_taken_(0) {
data_ = new PlatformData();
}

3
deps/v8/src/platform-linux.cc

@ -865,7 +865,8 @@ Sampler::Sampler(int interval, bool profiling)
: interval_(interval),
profiling_(profiling),
synchronous_(profiling),
active_(false) {
active_(false),
samples_taken_(0) {
data_ = new PlatformData(this);
}

3
deps/v8/src/platform-macos.cc

@ -634,7 +634,8 @@ Sampler::Sampler(int interval, bool profiling)
: interval_(interval),
profiling_(profiling),
synchronous_(profiling),
active_(false) {
active_(false),
samples_taken_(0) {
data_ = new PlatformData(this);
}

6
deps/v8/src/platform-openbsd.cc

@ -572,7 +572,11 @@ class Sampler::PlatformData : public Malloced {
Sampler::Sampler(int interval, bool profiling)
: interval_(interval), profiling_(profiling), active_(false) {
: interval_(interval),
profiling_(profiling),
synchronous_(profiling),
active_(false),
samples_taken_(0) {
data_ = new PlatformData();
}

3
deps/v8/src/platform-solaris.cc

@ -605,7 +605,8 @@ Sampler::Sampler(int interval, bool profiling)
: interval_(interval),
profiling_(profiling),
synchronous_(profiling),
active_(false) {
active_(false),
samples_taken_(0) {
data_ = new PlatformData();
}

3
deps/v8/src/platform-win32.cc

@ -1903,7 +1903,8 @@ Sampler::Sampler(int interval, bool profiling)
: interval_(interval),
profiling_(profiling),
synchronous_(profiling),
active_(false) {
active_(false),
samples_taken_(0) {
data_ = new PlatformData(this);
}

17
deps/v8/src/platform.h

@ -559,11 +559,14 @@ class TickSample {
class Sampler {
public:
// Initialize sampler.
explicit Sampler(int interval, bool profiling);
Sampler(int interval, bool profiling);
virtual ~Sampler();
// Performs stack sampling.
virtual void SampleStack(TickSample* sample) = 0;
void SampleStack(TickSample* sample) {
DoSampleStack(sample);
IncSamplesTaken();
}
// This method is called for each sampling period with the current
// program counter.
@ -585,14 +588,24 @@ class Sampler {
// Whether the sampler is running (that is, consumes resources).
bool IsActive() const { return active_; }
// Used in tests to make sure that stack sampling is performed.
int samples_taken() const { return samples_taken_; }
void ResetSamplesTaken() { samples_taken_ = 0; }
class PlatformData;
protected:
virtual void DoSampleStack(TickSample* sample) = 0;
private:
void IncSamplesTaken() { if (++samples_taken_ < 0) samples_taken_ = 0; }
const int interval_;
const bool profiling_;
const bool synchronous_;
bool active_;
PlatformData* data_; // Platform specific data.
int samples_taken_; // Counts stack samples taken.
DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
};

180
deps/v8/src/preparse-data.cc

@ -0,0 +1,180 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/v8stdint.h"
#include "globals.h"
#include "checks.h"
#include "allocation.h"
#include "utils.h"
#include "list-inl.h"
#include "hashmap.h"
#include "preparse-data.h"
namespace v8 {
namespace internal {
// ----------------------------------------------------------------------------
// FunctionLoggingParserRecorder
FunctionLoggingParserRecorder::FunctionLoggingParserRecorder()
: function_store_(0),
is_recording_(true),
pause_count_(0) {
preamble_[PreparseDataConstants::kMagicOffset] =
PreparseDataConstants::kMagicNumber;
preamble_[PreparseDataConstants::kVersionOffset] =
PreparseDataConstants::kCurrentVersion;
preamble_[PreparseDataConstants::kHasErrorOffset] = false;
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = 0;
preamble_[PreparseDataConstants::kSymbolCountOffset] = 0;
preamble_[PreparseDataConstants::kSizeOffset] = 0;
ASSERT_EQ(6, PreparseDataConstants::kHeaderSize);
#ifdef DEBUG
prev_start_ = -1;
#endif
}
void FunctionLoggingParserRecorder::LogMessage(int start_pos,
int end_pos,
const char* message,
const char* arg_opt) {
if (has_error()) return;
preamble_[PreparseDataConstants::kHasErrorOffset] = true;
function_store_.Reset();
STATIC_ASSERT(PreparseDataConstants::kMessageStartPos == 0);
function_store_.Add(start_pos);
STATIC_ASSERT(PreparseDataConstants::kMessageEndPos == 1);
function_store_.Add(end_pos);
STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2);
function_store_.Add((arg_opt == NULL) ? 0 : 1);
STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 3);
WriteString(CStrVector(message));
if (arg_opt) WriteString(CStrVector(arg_opt));
is_recording_ = false;
}
void FunctionLoggingParserRecorder::WriteString(Vector<const char> str) {
function_store_.Add(str.length());
for (int i = 0; i < str.length(); i++) {
function_store_.Add(str[i]);
}
}
// ----------------------------------------------------------------------------
// PartialParserRecorder - Record both function entries and symbols.
Vector<unsigned> PartialParserRecorder::ExtractData() {
int function_size = function_store_.size();
int total_size = PreparseDataConstants::kHeaderSize + function_size;
Vector<unsigned> data = Vector<unsigned>::New(total_size);
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size;
preamble_[PreparseDataConstants::kSymbolCountOffset] = 0;
memcpy(data.start(), preamble_, sizeof(preamble_));
int symbol_start = PreparseDataConstants::kHeaderSize + function_size;
if (function_size > 0) {
function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize,
symbol_start));
}
return data;
}
// ----------------------------------------------------------------------------
// CompleteParserRecorder - Record both function entries and symbols.
CompleteParserRecorder::CompleteParserRecorder()
: FunctionLoggingParserRecorder(),
symbol_store_(0),
symbol_entries_(0),
symbol_table_(vector_compare),
symbol_id_(0) {
}
void CompleteParserRecorder::LogSymbol(
int start, const char* literal_chars, int length) {
if (!is_recording_) return;
Vector<const char> literal(literal_chars, length);
int hash = vector_hash(literal);
HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
if (id == 0) {
// Put (symbol_id_ + 1) into entry and increment it.
id = ++symbol_id_;
entry->value = reinterpret_cast<void*>(id);
Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
entry->key = &symbol[0];
}
WriteNumber(id - 1);
}
Vector<unsigned> CompleteParserRecorder::ExtractData() {
int function_size = function_store_.size();
// Add terminator to symbols, then pad to unsigned size.
int symbol_size = symbol_store_.size();
int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned));
symbol_store_.AddBlock(padding, PreparseDataConstants::kNumberTerminator);
symbol_size += padding;
int total_size = PreparseDataConstants::kHeaderSize + function_size
+ (symbol_size / sizeof(unsigned));
Vector<unsigned> data = Vector<unsigned>::New(total_size);
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size;
preamble_[PreparseDataConstants::kSymbolCountOffset] = symbol_id_;
memcpy(data.start(), preamble_, sizeof(preamble_));
int symbol_start = PreparseDataConstants::kHeaderSize + function_size;
if (function_size > 0) {
function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize,
symbol_start));
}
if (!has_error()) {
symbol_store_.WriteTo(
Vector<byte>::cast(data.SubVector(symbol_start, total_size)));
}
return data;
}
void CompleteParserRecorder::WriteNumber(int number) {
ASSERT(number >= 0);
int mask = (1 << 28) - 1;
for (int i = 28; i > 0; i -= 7) {
if (number > mask) {
symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u);
number &= mask;
}
mask >>= 7;
}
symbol_store_.Add(static_cast<byte>(number));
}
} } // namespace v8::internal.

223
deps/v8/src/preparse-data.h

@ -0,0 +1,223 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_PREPARSER_DATA_H_
#define V8_PREPARSER_DATA_H_
#include "hashmap.h"
namespace v8 {
namespace internal {
// Generic and general data used by preparse data recorders and readers.
class PreparseDataConstants : public AllStatic {
public:
// Layout and constants of the preparse data exchange format.
static const unsigned kMagicNumber = 0xBadDead;
static const unsigned kCurrentVersion = 5;
static const int kMagicOffset = 0;
static const int kVersionOffset = 1;
static const int kHasErrorOffset = 2;
static const int kFunctionsSizeOffset = 3;
static const int kSymbolCountOffset = 4;
static const int kSizeOffset = 5;
static const int kHeaderSize = 6;
// If encoding a message, the following positions are fixed.
static const int kMessageStartPos = 0;
static const int kMessageEndPos = 1;
static const int kMessageArgCountPos = 2;
static const int kMessageTextPos = 3;
static const byte kNumberTerminator = 0x80u;
};
// ----------------------------------------------------------------------------
// ParserRecorder - Logging of preparser data.
// Abstract interface for preparse data recorder.
class ParserRecorder {
public:
ParserRecorder() { }
virtual ~ParserRecorder() { }
// Logs the scope and some details of a function literal in the source.
virtual void LogFunction(int start,
int end,
int literals,
int properties) = 0;
// Logs a symbol creation of a literal or identifier.
virtual void LogSymbol(int start, const char* symbol, int length) = 0;
// Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector
// representing the error only.
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt) = 0;
virtual int function_position() = 0;
virtual int symbol_position() = 0;
virtual int symbol_ids() = 0;
virtual Vector<unsigned> ExtractData() = 0;
virtual void PauseRecording() = 0;
virtual void ResumeRecording() = 0;
};
// ----------------------------------------------------------------------------
// FunctionLoggingParserRecorder - Record only function entries
class FunctionLoggingParserRecorder : public ParserRecorder {
public:
FunctionLoggingParserRecorder();
virtual ~FunctionLoggingParserRecorder() {}
virtual void LogFunction(int start, int end, int literals, int properties) {
function_store_.Add(start);
function_store_.Add(end);
function_store_.Add(literals);
function_store_.Add(properties);
}
// Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector
// representing the error only.
virtual void LogMessage(int start,
int end,
const char* message,
const char* argument_opt);
virtual int function_position() { return function_store_.size(); }
virtual Vector<unsigned> ExtractData() = 0;
virtual void PauseRecording() {
pause_count_++;
is_recording_ = false;
}
virtual void ResumeRecording() {
ASSERT(pause_count_ > 0);
if (--pause_count_ == 0) is_recording_ = !has_error();
}
protected:
bool has_error() {
return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]);
}
bool is_recording() {
return is_recording_;
}
void WriteString(Vector<const char> str);
Collector<unsigned> function_store_;
unsigned preamble_[PreparseDataConstants::kHeaderSize];
bool is_recording_;
int pause_count_;
#ifdef DEBUG
int prev_start_;
#endif
};
// ----------------------------------------------------------------------------
// PartialParserRecorder - Record only function entries
class PartialParserRecorder : public FunctionLoggingParserRecorder {
public:
PartialParserRecorder() : FunctionLoggingParserRecorder() { }
virtual void LogSymbol(int start, const char* symbol, int length) { }
virtual ~PartialParserRecorder() { }
virtual Vector<unsigned> ExtractData();
virtual int symbol_position() { return 0; }
virtual int symbol_ids() { return 0; }
};
// ----------------------------------------------------------------------------
// CompleteParserRecorder - Record both function entries and symbols.
class CompleteParserRecorder: public FunctionLoggingParserRecorder {
public:
CompleteParserRecorder();
virtual ~CompleteParserRecorder() { }
virtual void LogSymbol(int start, const char* symbol, int length);
virtual Vector<unsigned> ExtractData();
virtual int symbol_position() { return symbol_store_.size(); }
virtual int symbol_ids() { return symbol_id_; }
private:
static int vector_hash(Vector<const char> string) {
int hash = 0;
for (int i = 0; i < string.length(); i++) {
int c = string[i];
hash += c;
hash += (hash << 10);
hash ^= (hash >> 6);
}
return hash;
}
static bool vector_compare(void* a, void* b) {
Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a);
Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b);
int length = string1->length();
if (string2->length() != length) return false;
return memcmp(string1->start(), string2->start(), length) == 0;
}
// Write a non-negative number to the symbol store.
void WriteNumber(int number);
Collector<byte> symbol_store_;
Collector<Vector<const char> > symbol_entries_;
HashMap symbol_table_;
int symbol_id_;
};
} } // namespace v8::internal.
#endif // V8_PREPARSER_DATA_H_

1184
deps/v8/src/preparser.cc

File diff suppressed because it is too large

1188
deps/v8/src/preparser.h

File diff suppressed because it is too large

23
deps/v8/src/profile-generator.cc

@ -1295,8 +1295,8 @@ HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
} else if (object->IsJSObject()) {
return AddEntry(object,
HeapEntry::kObject,
collection_->GetName(
JSObject::cast(object)->constructor_name()),
collection_->GetName(GetConstructorNameForHeapProfile(
JSObject::cast(object))),
children_count,
retainers_count);
} else if (object->IsString()) {
@ -1462,6 +1462,14 @@ void HeapSnapshot::BuildDominatorTree(const Vector<HeapEntry*>& entries,
}
void HeapSnapshot::SetDominatorsToSelf() {
for (int i = 0; i < entries_.length(); ++i) {
HeapEntry* entry = entries_[i];
if (entry->dominator() == NULL) entry->set_dominator(entry);
}
}
void HeapSnapshot::SetEntriesDominators() {
// This array is used for maintaining reverse postorder of nodes.
ScopedVector<HeapEntry*> ordered_entries(entries_.length());
@ -1473,10 +1481,7 @@ void HeapSnapshot::SetEntriesDominators() {
ordered_entries[i]->set_dominator(dominators[i]);
}
// For nodes unreachable from root, set dominator to itself.
for (int i = 0; i < entries_.length(); ++i) {
HeapEntry* entry = entries_[i];
if (entry->dominator() == NULL) entry->set_dominator(entry);
}
SetDominatorsToSelf();
}
@ -2764,6 +2769,12 @@ void HeapSnapshotJSONSerializer::SortHashMap(
sorted_entries->Sort(SortUsingEntryValue);
}
String* GetConstructorNameForHeapProfile(JSObject* object) {
if (object->IsJSFunction()) return Heap::closure_symbol();
return object->constructor_name();
}
} } // namespace v8::internal
#endif // ENABLE_LOGGING_AND_PROFILING

4
deps/v8/src/profile-generator.h

@ -700,6 +700,7 @@ class HeapSnapshot {
List<HeapEntry*>* GetSortedEntriesList();
template<class Visitor>
void IterateEntries(Visitor* visitor) { entries_.Iterate(visitor); }
void SetDominatorsToSelf();
void Print(int max_depth);
void PrintEntriesSize();
@ -1072,6 +1073,9 @@ class HeapSnapshotJSONSerializer {
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer);
};
String* GetConstructorNameForHeapProfile(JSObject* object);
} } // namespace v8::internal
#endif // ENABLE_LOGGING_AND_PROFILING

8
deps/v8/src/runtime.cc

@ -5020,11 +5020,12 @@ static int CopyCachedAsciiCharsToArray(const char* chars,
// For example, "foo" => ["f", "o", "o"].
static MaybeObject* Runtime_StringToArray(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 1);
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(String, s, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
s->TryFlatten();
const int length = s->length();
const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
Handle<FixedArray> elements;
if (s->IsFlat() && s->IsAsciiRepresentation()) {
@ -6391,7 +6392,7 @@ static void TrySettingInlineConstructStub(Handle<JSFunction> function) {
}
if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
ConstructStubCompiler compiler;
MaybeObject* code = compiler.CompileConstructStub(function->shared());
MaybeObject* code = compiler.CompileConstructStub(*function);
if (!code->IsFailure()) {
function->shared()->set_construct_stub(
Code::cast(code->ToObjectUnchecked()));
@ -6459,7 +6460,6 @@ static MaybeObject* Runtime_NewObject(Arguments args) {
// track one initial_map at a time, so we force the completion before the
// function is called as a constructor for the first time.
shared->CompleteInobjectSlackTracking();
TrySettingInlineConstructStub(function);
}
bool first_allocation = !shared->live_objects_may_exist();

2
deps/v8/src/runtime.h

@ -175,7 +175,7 @@ namespace internal {
F(StringReplaceRegExpWithString, 4, 1) \
F(StringMatch, 3, 1) \
F(StringTrim, 3, 1) \
F(StringToArray, 1, 1) \
F(StringToArray, 2, 1) \
F(NewStringWrapper, 1, 1) \
\
/* Numbers */ \

2
deps/v8/src/string.js

@ -552,7 +552,7 @@ function StringSplit(separator, limit) {
var separator_length = separator.length;
// If the separator string is empty then return the elements in the subject.
if (separator_length === 0) return %StringToArray(subject);
if (separator_length === 0) return %StringToArray(subject, limit);
var result = %StringSplit(subject, separator, limit);

2
deps/v8/src/stub-cache.h

@ -740,7 +740,7 @@ class ConstructStubCompiler: public StubCompiler {
public:
explicit ConstructStubCompiler() {}
MUST_USE_RESULT MaybeObject* CompileConstructStub(SharedFunctionInfo* shared);
MUST_USE_RESULT MaybeObject* CompileConstructStub(JSFunction* function);
private:
MaybeObject* GetCode();

3
deps/v8/src/token.cc

@ -25,8 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "v8.h"
#include "../include/v8stdint.h"
#include "token.h"
namespace v8 {

2
deps/v8/src/v8.h

@ -54,7 +54,7 @@
// Basic includes
#include "../include/v8.h"
#include "v8globals.h"
#include "checks.h"
#include "v8checks.h"
#include "allocation.h"
#include "v8utils.h"
#include "flags.h"

64
deps/v8/src/v8checks.h

@ -0,0 +1,64 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_V8CHECKS_H_
#define V8_V8CHECKS_H_
#include "checks.h"
void API_Fatal(const char* location, const char* format, ...);
namespace v8 {
class Value;
template <class T> class Handle;
namespace internal {
intptr_t HeapObjectTagMask();
} } // namespace v8::internal
void CheckNonEqualsHelper(const char* file,
int line,
const char* unexpected_source,
v8::Handle<v8::Value> unexpected,
const char* value_source,
v8::Handle<v8::Value> value);
void CheckEqualsHelper(const char* file,
int line,
const char* expected_source,
v8::Handle<v8::Value> expected,
const char* value_source,
v8::Handle<v8::Value> value);
#define ASSERT_TAG_ALIGNED(address) \
ASSERT((reinterpret_cast<intptr_t>(address) & HeapObjectTagMask()) == 0)
#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & HeapObjectTagMask()) == 0)
#endif // V8_V8CHECKS_H_

4
deps/v8/src/version.cc

@ -34,8 +34,8 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 2
#define MINOR_VERSION 5
#define BUILD_NUMBER 8
#define PATCH_LEVEL 0
#define BUILD_NUMBER 9
#define PATCH_LEVEL 1
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the

8
deps/v8/src/x64/macro-assembler-x64.cc

@ -1889,7 +1889,6 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
void MacroAssembler::LoadAllocationTopHelper(Register result,
Register result_end,
Register scratch,
AllocationFlags flags) {
ExternalReference new_space_allocation_top =
@ -1911,7 +1910,6 @@ void MacroAssembler::LoadAllocationTopHelper(Register result,
// Move address of new object to result. Use scratch register if available,
// and keep address in scratch until call to UpdateAllocationTopHelper.
if (scratch.is_valid()) {
ASSERT(!scratch.is(result_end));
movq(scratch, new_space_allocation_top);
movq(result, Operand(scratch, 0));
} else if (result.is(rax)) {
@ -1972,7 +1970,7 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
ASSERT(!result.is(result_end));
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
LoadAllocationTopHelper(result, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
@ -2029,7 +2027,7 @@ void MacroAssembler::AllocateInNewSpace(int header_size,
ASSERT(!result.is(result_end));
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
LoadAllocationTopHelper(result, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
@ -2071,7 +2069,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
ASSERT(!result.is(result_end));
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
LoadAllocationTopHelper(result, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =

3
deps/v8/src/x64/macro-assembler-x64.h

@ -950,12 +950,9 @@ class MacroAssembler: public Assembler {
// Allocation support helpers.
// Loads the top of new-space into the result register.
// If flags contains RESULT_CONTAINS_TOP then result_end is valid and
// already contains the top of new-space, and scratch is invalid.
// Otherwise the address of the new-space top is loaded into scratch (if
// scratch is valid), and the new-space top is loaded into result.
void LoadAllocationTopHelper(Register result,
Register result_end,
Register scratch,
AllocationFlags flags);
// Update allocation top with value in result_end register.

7
deps/v8/src/x64/stub-cache-x64.cc

@ -2890,8 +2890,7 @@ void StubCompiler::GenerateLoadConstant(JSObject* object,
// Specialized stub for constructing objects from functions which only have only
// simple assignments of the form this.x = ...; in their body.
MaybeObject* ConstructStubCompiler::CompileConstructStub(
SharedFunctionInfo* shared) {
MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
// ----------- S t a t e -------------
// -- rax : argc
// -- rdi : constructor
@ -2964,6 +2963,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(
// r9: first in-object property of the JSObject
// Fill the initialized properties with a constant value or a passed argument
// depending on the this.x = ...; assignment in the function.
SharedFunctionInfo* shared = function->shared();
for (int i = 0; i < shared->this_property_assignments_count(); i++) {
if (shared->IsThisPropertyAssignmentArgument(i)) {
// Check if the argument assigned to the property is actually passed.
@ -2983,8 +2983,9 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(
}
// Fill the unused in-object property fields with undefined.
ASSERT(function->has_initial_map());
for (int i = shared->this_property_assignments_count();
i < shared->CalculateInObjectProperties();
i < function->initial_map()->inobject_properties();
i++) {
__ movq(Operand(r9, i * kPointerSize), r8);
}

27
deps/v8/test/cctest/test-api.cc

@ -7819,6 +7819,31 @@ THREADED_TEST(ObjectProtoToString) {
}
THREADED_TEST(ObjectGetConstructorName) {
v8::HandleScope scope;
LocalContext context;
v8_compile("function Parent() {};"
"function Child() {};"
"Child.prototype = new Parent();"
"var outer = { inner: function() { } };"
"var p = new Parent();"
"var c = new Child();"
"var x = new outer.inner();")->Run();
Local<v8::Value> p = context->Global()->Get(v8_str("p"));
CHECK(p->IsObject() && p->ToObject()->GetConstructorName()->Equals(
v8_str("Parent")));
Local<v8::Value> c = context->Global()->Get(v8_str("c"));
CHECK(c->IsObject() && c->ToObject()->GetConstructorName()->Equals(
v8_str("Child")));
Local<v8::Value> x = context->Global()->Get(v8_str("x"));
CHECK(x->IsObject() && x->ToObject()->GetConstructorName()->Equals(
v8_str("outer.inner")));
}
bool ApiTestFuzzer::fuzzing_ = false;
i::Semaphore* ApiTestFuzzer::all_tests_done_=
i::OS::CreateSemaphore(0);
@ -8734,7 +8759,7 @@ TEST(PreCompileInvalidPreparseDataError) {
v8::ScriptData::PreCompile(script, i::StrLength(script));
CHECK(!sd->HasError());
// ScriptDataImpl private implementation details
const int kHeaderSize = i::ScriptDataImpl::kHeaderSize;
const int kHeaderSize = i::PreparseDataConstants::kHeaderSize;
const int kFunctionEntrySize = i::FunctionEntry::kSize;
const int kFunctionEntryStartOffset = 0;
const int kFunctionEntryEndOffset = 1;

6
deps/v8/test/cctest/test-conversions.cc

@ -104,8 +104,10 @@ TEST(IntegerStrLiteral) {
CHECK_EQ(0.0, StringToDouble("000", NO_FLAGS));
CHECK_EQ(1.0, StringToDouble("1", NO_FLAGS));
CHECK_EQ(-1.0, StringToDouble("-1", NO_FLAGS));
CHECK_EQ(-1.0, StringToDouble(" - 1 ", NO_FLAGS));
CHECK_EQ(1.0, StringToDouble(" + 1 ", NO_FLAGS));
CHECK_EQ(-1.0, StringToDouble(" -1 ", NO_FLAGS));
CHECK_EQ(1.0, StringToDouble(" +1 ", NO_FLAGS));
CHECK(isnan(StringToDouble(" - 1 ", NO_FLAGS)));
CHECK(isnan(StringToDouble(" + 1 ", NO_FLAGS)));
CHECK_EQ(0.0, StringToDouble("0e0", ALLOW_HEX | ALLOW_OCTALS));
CHECK_EQ(0.0, StringToDouble("0e1", ALLOW_HEX | ALLOW_OCTALS));

15
deps/v8/test/cctest/test-heap-profiler.cc

@ -1178,4 +1178,19 @@ TEST(HeapSnapshotJSONSerializationAborting) {
CHECK_EQ(0, stream.eos_signaled());
}
// Must not crash in debug mode.
TEST(AggregatedHeapSnapshotJSONSerialization) {
v8::HandleScope scope;
LocalContext env;
const v8::HeapSnapshot* snapshot =
v8::HeapProfiler::TakeSnapshot(
v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
TestJSONStream stream;
snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
CHECK_GT(stream.size(), 0);
CHECK_EQ(1, stream.eos_signaled());
}
#endif // ENABLE_LOGGING_AND_PROFILING

42
deps/v8/test/cctest/test-log.cc

@ -139,6 +139,12 @@ namespace internal {
class LoggerTestHelper : public AllStatic {
public:
static bool IsSamplerActive() { return Logger::IsProfilerSamplerActive(); }
static void ResetSamplesTaken() {
reinterpret_cast<Sampler*>(Logger::ticker_)->ResetSamplesTaken();
}
static bool has_samples_taken() {
return reinterpret_cast<Sampler*>(Logger::ticker_)->samples_taken() > 0;
}
};
} // namespace v8::internal
@ -147,24 +153,6 @@ class LoggerTestHelper : public AllStatic {
using v8::internal::LoggerTestHelper;
// Under Linux, we need to check if signals were delivered to avoid false
// positives. Under other platforms profiling is done via a high-priority
// thread, so this case never happen.
static bool was_sigprof_received = true;
#ifdef __linux__
struct sigaction old_sigprof_handler;
pthread_t our_thread;
static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) {
if (signal != SIGPROF || !pthread_equal(pthread_self(), our_thread)) return;
was_sigprof_received = true;
old_sigprof_handler.sa_sigaction(signal, info, context);
}
#endif // __linux__
namespace {
class ScopedLoggerInitializer {
@ -258,6 +246,9 @@ class LogBufferMatcher {
static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
CHECK(!LoggerTestHelper::IsSamplerActive());
LoggerTestHelper::ResetSamplesTaken();
Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
CHECK(LoggerTestHelper::IsSamplerActive());
@ -266,19 +257,6 @@ static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/
CHECK_NE(NULL, matcher->Find(code_creation));
#ifdef __linux__
// Intercept SIGPROF handler to make sure that the test process
// had received it. Under load, system can defer it causing test failure.
// It is important to execute this after 'ResumeProfiler'.
our_thread = pthread_self();
was_sigprof_received = false;
struct sigaction sa;
sa.sa_sigaction = SigProfSignalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
CHECK_EQ(0, sigaction(SIGPROF, &sa, &old_sigprof_handler));
#endif // __linux__
// Force compiler to generate new code by parametrizing source.
EmbeddedVector<char, 100> script_src;
i::OS::SNPrintF(script_src,
@ -306,7 +284,7 @@ static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
CHECK_NE(NULL, matcher->Find(code_creation));
const char* tick = "\ntick,";
const bool ticks_found = matcher->Find(tick) != NULL;
CHECK_EQ(was_sigprof_received, ticks_found);
CHECK_EQ(LoggerTestHelper::has_samples_taken(), ticks_found);
}

3
deps/v8/test/cctest/test-parsing.cc

@ -263,8 +263,7 @@ TEST(StandAlonePreParser) {
i::CompleteParserRecorder log;
i::V8JavaScriptScanner scanner;
scanner.Initialize(i::Handle<i::String>::null(), &stream);
v8::preparser::PreParser<i::V8JavaScriptScanner,
i::CompleteParserRecorder> preparser;
v8::preparser::PreParser preparser;
bool result = preparser.PreParseProgram(&scanner, &log, true);
CHECK(result);
i::ScriptDataImpl data(log.ExtractData());

46
deps/v8/test/mjsunit/regress/regress-944.js

@ -0,0 +1,46 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Check for parsing of proper ES5 15.9.1.15 (ISO 8601 / RFC 3339) time
// strings that contain millisecond values with exactly 3 digits (as is
// required by the spec format if the string has milliseconds at all).
assertEquals(1290722550521, Date.parse("2010-11-25T22:02:30.521Z"));
// Check for parsing of extension/generalization of the ES5 15.9.1.15 spec
// format where millisecond values have only 1 or 2 digits.
assertEquals(1290722550500, Date.parse("2010-11-25T22:02:30.5Z"));
assertEquals(1290722550520, Date.parse("2010-11-25T22:02:30.52Z"));
assertFalse(Date.parse("2010-11-25T22:02:30.5Z") === Date.parse("2010-11-25T22:02:30.005Z"));
// Check that we truncate millisecond values having more than 3 digits.
assertEquals(Date.parse("2010-11-25T22:02:30.1005Z"), Date.parse("2010-11-25T22:02:30.100Z"));
// Check that we accept lots of digits.
assertEquals(Date.parse("2010-11-25T22:02:30.999Z"), Date.parse("2010-11-25T22:02:30.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999Z"));
// Fail if there's a decimal point but zero digits for (expected) milliseconds.
assertTrue(isNaN(Date.parse("2010-11-25T22:02:30.Z")));

19
deps/v8/test/mjsunit/string-split.js

@ -97,3 +97,22 @@ assertEquals([""], ''.split(/./));
assertEquals([], ''.split(/.?/));
assertEquals([], ''.split(/.??/));
assertEquals([], ''.split(/()()/));
// Issue http://code.google.com/p/v8/issues/detail?id=929
// (Splitting with empty separator and a limit.)
function numberObj(num) {
return {valueOf: function() { return num; }};
}
assertEquals([], "abc".split("", 0));
assertEquals([], "abc".split("", numberObj(0)));
assertEquals(["a"], "abc".split("", 1));
assertEquals(["a"], "abc".split("", numberObj(1)));
assertEquals(["a", "b"], "abc".split("", 2));
assertEquals(["a", "b"], "abc".split("", numberObj(2)));
assertEquals(["a", "b", "c"], "abc".split("", 3));
assertEquals(["a", "b", "c"], "abc".split("", numberObj(3)));
assertEquals(["a", "b", "c"], "abc".split("", 4));
assertEquals(["a", "b", "c"], "abc".split("", numberObj(4)));

7
deps/v8/tools/gyp/v8.gyp

@ -406,6 +406,10 @@
'../../src/parser.cc',
'../../src/parser.h',
'../../src/platform.h',
'../../src/preparse-data.cc',
'../../src/preparse-data.h',
'../../src/preparser.cc',
'../../src/preparser.h',
'../../src/prettyprinter.cc',
'../../src/prettyprinter.h',
'../../src/property.cc',
@ -471,8 +475,11 @@
'../../src/v8-counters.h',
'../../src/v8.cc',
'../../src/v8.h',
'../../src/v8checks.h',
'../../src/v8globals.h',
'../../src/v8threads.cc',
'../../src/v8threads.h',
'../../src/v8utils.h',
'../../src/variables.cc',
'../../src/variables.h',
'../../src/version.cc',

2
deps/v8/tools/presubmit.py

@ -195,7 +195,7 @@ class CppLintProcessor(SourceFileProcessor):
or (name in CppLintProcessor.IGNORE_LINT))
def GetPathsToSearch(self):
return ['src', 'include', 'samples', join('test', 'cctest')]
return ['src', 'preparser', 'include', 'samples', join('test', 'cctest')]
def ProcessFiles(self, files, path):
good_files_cache = FileContentsCache('.cpplint-cache')

32
deps/v8/tools/visual_studio/v8_base.vcproj

@ -761,6 +761,22 @@
RelativePath="..\..\src\parser.h"
>
</File>
<File
RelativePath="..\..\src\preparser.cc"
>
</File>
<File
RelativePath="..\..\src\preparser.h"
>
</File>
<File
RelativePath="..\..\src\preparse-data.cc"
>
</File>
<File
RelativePath="..\..\src\preparse-data.h"
>
</File>
<File
RelativePath="..\..\src\profile-generator.cc"
>
@ -1033,6 +1049,14 @@
RelativePath="..\..\src\v8.h"
>
</File>
<File
RelativePath="..\..\src\v8checks.h"
>
</File>
<File
RelativePath="..\..\src\v8globals.h"
>
</File>
<File
RelativePath="..\..\src\v8threads.cc"
>
@ -1041,6 +1065,10 @@
RelativePath="..\..\src\v8threads.h"
>
</File>
<File
RelativePath="..\..\src\v8utils.h"
>
</File>
<File
RelativePath="..\..\src\variables.cc"
>
@ -1157,6 +1185,10 @@
RelativePath="..\..\include\v8.h"
>
</File>
<File
RelativePath="..\..\include\v8stdint.h"
>
</File>
</Filter>
</Files>
<Globals>

Loading…
Cancel
Save