Version 2.2.3
Added stack command and mem command to ARM simulator debugger.
Fixed scons snapshot and ARM build, and Windows X64 build issues.
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@4410 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index bf018ed..2c0da0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-14: Version 2.2.3
+
+ Added stack command and mem command to ARM simulator debugger.
+
+ Fixed scons snapshot and ARM build, and Windows X64 build issues.
+
+ Performance improvements on all platforms.
+
+
2010-04-12: Version 2.2.2
Introduced new profiler API.
diff --git a/SConstruct b/SConstruct
index efdd15c..1625b7a 100644
--- a/SConstruct
+++ b/SConstruct
@@ -52,9 +52,10 @@
GCC_EXTRA_CCFLAGS = []
GCC_DTOA_EXTRA_CCFLAGS = []
-ANDROID_FLAGS = ['-march=armv5te',
- '-mtune=xscale',
- '-msoft-float',
+ANDROID_FLAGS = ['-march=armv7-a',
+ '-mtune=cortex-a8',
+ '-mfloat-abi=softfp',
+ '-mfpu=vfp',
'-fpic',
'-mthumb-interwork',
'-funwind-tables',
@@ -69,6 +70,8 @@
'-fomit-frame-pointer',
'-fno-strict-aliasing',
'-finline-limit=64',
+ '-DCAN_USE_VFP_INSTRUCTIONS=1',
+ '-DCAN_USE_ARMV7_INSTRUCTIONS=1',
'-MD']
ANDROID_INCLUDES = [ANDROID_TOP + '/bionic/libc/arch-arm/include',
diff --git a/include/v8.h b/include/v8.h
index db739bb..d90289a 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -859,18 +859,23 @@
* \return The number of bytes copied to the buffer
* excluding the NULL terminator.
*/
- int Write(uint16_t* buffer, int start = 0, int length = -1) const; // UTF-16
- int WriteAscii(char* buffer, int start = 0, int length = -1) const; // ASCII
+ enum WriteHints {
+ NO_HINTS = 0,
+ HINT_MANY_WRITES_EXPECTED = 1
+ };
+
+ int Write(uint16_t* buffer,
+ int start = 0,
+ int length = -1,
+ WriteHints hints = NO_HINTS) const; // UTF-16
+ int WriteAscii(char* buffer,
+ int start = 0,
+ int length = -1,
+ WriteHints hints = NO_HINTS) const; // ASCII
int WriteUtf8(char* buffer,
int length = -1,
- int* nchars_ref = NULL) const; // UTF-8
-
- /**
- * Flatten internal memory. Operations on the string tend to run faster
- * after flattening especially if the string is a concatenation of many
- * others.
- */
- void Flatten();
+ int* nchars_ref = NULL,
+ WriteHints hints = NO_HINTS) const; // UTF-8
/**
* A zero length string.
diff --git a/src/SConscript b/src/SConscript
index 3eaa6cb..5add999 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -306,7 +306,12 @@
source_objs = context.ConfigureObject(env, source_files)
non_snapshot_files = [dtoa_obj, source_objs]
- # Create snapshot if necessary.
+ # Create snapshot if necessary. For cross compilation you should either
+ # do without snapshots and take the performance hit or you should build a
+ # host VM with the simulator=arm and snapshot=on options and then take the
+ # resulting snapshot.cc file from obj/release and put it in the src
+ # directory. Then rebuild the VM with the cross compiler and specify
+ # snapshot=nobuild on the scons command line.
empty_snapshot_obj = context.ConfigureObject(env, 'snapshot-empty.cc')
mksnapshot_env = env.Copy()
mksnapshot_env.Replace(**context.flags['mksnapshot'])
@@ -316,7 +321,7 @@
if context.build_snapshot:
snapshot_cc = env.Snapshot('snapshot.cc', mksnapshot, LOGFILE=File('snapshot.log').abspath)
else:
- snapshot_cc = Command('snapshot.cc', [], [])
+ snapshot_cc = 'snapshot.cc'
snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.'])
else:
snapshot_obj = empty_snapshot_obj
diff --git a/src/api.cc b/src/api.cc
index 2c7975b..47950eb 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2641,12 +2641,20 @@
}
-int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref) const {
+int String::WriteUtf8(char* buffer,
+ int capacity,
+ int* nchars_ref,
+ WriteHints hints) const {
if (IsDeadCheck("v8::String::WriteUtf8()")) return 0;
LOG_API("String::WriteUtf8");
ENTER_V8;
i::Handle<i::String> str = Utils::OpenHandle(this);
StringTracker::RecordWrite(str);
+ if (hints & HINT_MANY_WRITES_EXPECTED) {
+ // Flatten the string for efficiency. This applies whether we are
+ // using StringInputBuffer or Get(i) to access the characters.
+ str->TryFlatten();
+ }
write_input_buffer.Reset(0, *str);
int len = str->length();
// Encode the first K - 3 bytes directly into the buffer since we
@@ -2688,16 +2696,21 @@
}
-int String::WriteAscii(char* buffer, int start, int length) const {
+int String::WriteAscii(char* buffer,
+ int start,
+ int length,
+ WriteHints hints) const {
if (IsDeadCheck("v8::String::WriteAscii()")) return 0;
LOG_API("String::WriteAscii");
ENTER_V8;
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
StringTracker::RecordWrite(str);
- // Flatten the string for efficiency. This applies whether we are
- // using StringInputBuffer or Get(i) to access the characters.
- str->TryFlatten();
+ if (hints & HINT_MANY_WRITES_EXPECTED) {
+ // Flatten the string for efficiency. This applies whether we are
+ // using StringInputBuffer or Get(i) to access the characters.
+ str->TryFlatten();
+ }
int end = length;
if ( (length == -1) || (length > str->length() - start) )
end = str->length() - start;
@@ -2715,13 +2728,21 @@
}
-int String::Write(uint16_t* buffer, int start, int length) const {
+int String::Write(uint16_t* buffer,
+ int start,
+ int length,
+ WriteHints hints) const {
if (IsDeadCheck("v8::String::Write()")) return 0;
LOG_API("String::Write");
ENTER_V8;
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
StringTracker::RecordWrite(str);
+ if (hints & HINT_MANY_WRITES_EXPECTED) {
+ // Flatten the string for efficiency. This applies whether we are
+ // using StringInputBuffer or Get(i) to access the characters.
+ str->TryFlatten();
+ }
int end = length;
if ( (length == -1) || (length > str->length() - start) )
end = str->length() - start;
@@ -2733,13 +2754,6 @@
}
-void v8::String::Flatten() {
- if (IsDeadCheck("v8::String::Flatten()")) return;
- i::Handle<i::String> str = Utils::OpenHandle(this);
- i::FlattenString(str);
-}
-
-
bool v8::String::IsExternal() const {
EnsureInitialized("v8::String::IsExternal()");
i::Handle<i::String> str = Utils::OpenHandle(this);
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 92dcdd1..0fc7b6d 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -4021,6 +4021,100 @@
}
+void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
+ // No stub. This code only occurs a few times in regexp.js.
+ const int kMaxInlineLength = 100;
+ ASSERT_EQ(3, args->length());
+ Load(args->at(0)); // Size of array, smi.
+ Load(args->at(1)); // "index" property value.
+ Load(args->at(2)); // "input" property value.
+ {
+ VirtualFrame::SpilledScope spilled_scope(frame_);
+ Label slowcase;
+ Label done;
+ __ ldr(r1, MemOperand(sp, kPointerSize * 2));
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+ __ tst(r1, Operand(kSmiTagMask));
+ __ b(ne, &slowcase);
+ __ cmp(r1, Operand(Smi::FromInt(kMaxInlineLength)));
+ __ b(hi, &slowcase);
+ // Smi-tagging is equivalent to multiplying by 2.
+ // Allocate RegExpResult followed by FixedArray with size in ebx.
+ // JSArray: [Map][empty properties][Elements][Length-smi][index][input]
+ // Elements: [Map][Length][..elements..]
+ // Size of JSArray with two in-object properties and the header of a
+ // FixedArray.
+ int objects_size =
+ (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize;
+ __ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize));
+ __ add(r2, r5, Operand(objects_size));
+ __ AllocateInNewSpace(r2, // In: Size, in words.
+ r0, // Out: Start of allocation (tagged).
+ r3, // Scratch register.
+ r4, // Scratch register.
+ &slowcase,
+ TAG_OBJECT);
+ // r0: Start of allocated area, object-tagged.
+ // r1: Number of elements in array, as smi.
+ // r5: Number of elements, untagged.
+
+ // Set JSArray map to global.regexp_result_map().
+ // Set empty properties FixedArray.
+ // Set elements to point to FixedArray allocated right after the JSArray.
+ // Interleave operations for better latency.
+ __ ldr(r2, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ add(r3, r0, Operand(JSRegExpResult::kSize));
+ __ mov(r4, Operand(Factory::empty_fixed_array()));
+ __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
+ __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
+ __ ldr(r2, ContextOperand(r2, Context::REGEXP_RESULT_MAP_INDEX));
+ __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
+ __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
+
+ // Set input, index and length fields from arguments.
+ __ ldm(ia_w, sp, static_cast<RegList>(r2.bit() | r4.bit()));
+ __ str(r1, FieldMemOperand(r0, JSArray::kLengthOffset));
+ __ add(sp, sp, Operand(kPointerSize));
+ __ str(r4, FieldMemOperand(r0, JSRegExpResult::kIndexOffset));
+ __ str(r2, FieldMemOperand(r0, JSRegExpResult::kInputOffset));
+
+ // Fill out the elements FixedArray.
+ // r0: JSArray, tagged.
+ // r3: FixedArray, tagged.
+ // r5: Number of elements in array, untagged.
+
+ // Set map.
+ __ mov(r2, Operand(Factory::fixed_array_map()));
+ __ str(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
+ // Set FixedArray length.
+ __ str(r5, FieldMemOperand(r3, FixedArray::kLengthOffset));
+ // Fill contents of fixed-array with the-hole.
+ __ mov(r2, Operand(Factory::the_hole_value()));
+ __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ // Fill fixed array elements with hole.
+ // r0: JSArray, tagged.
+ // r2: the hole.
+ // r3: Start of elements in FixedArray.
+ // r5: Number of elements to fill.
+ Label loop;
+ __ tst(r5, Operand(r5));
+ __ bind(&loop);
+ __ b(le, &done); // Jump if r1 is negative or zero.
+ __ sub(r5, r5, Operand(1), SetCC);
+ __ str(r2, MemOperand(r3, r5, LSL, kPointerSizeLog2));
+ __ jmp(&loop);
+
+ __ bind(&slowcase);
+ __ CallRuntime(Runtime::kRegExpConstructResult, 3);
+
+ __ bind(&done);
+ }
+ frame_->Forget(3);
+ frame_->EmitPush(r0);
+}
+
+
void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 62e9fe4..74aed1d 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -407,6 +407,8 @@
// Support for direct calls from JavaScript to native RegExp code.
void GenerateRegExpExec(ZoneList<Expression*>* args);
+ void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
+
// Fast support for number to string.
void GenerateNumberToString(ZoneList<Expression*>* args);
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 8a6588b..b18fd79 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -150,7 +150,11 @@
*value = GetRegisterValue(regnum);
return true;
} else {
- return SScanF(desc, "%i", value) == 1;
+ if (strncmp(desc, "0x", 2) == 0) {
+ return SScanF(desc + 2, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
+ } else {
+ return SScanF(desc, "%u", reinterpret_cast<uint32_t*>(value)) == 1;
+ }
}
return false;
}
@@ -231,6 +235,7 @@
char cmd[COMMAND_SIZE + 1];
char arg1[ARG_SIZE + 1];
char arg2[ARG_SIZE + 1];
+ char* argv[3] = { cmd, arg1, arg2 };
// make sure to have a proper terminating character if reaching the limit
cmd[COMMAND_SIZE] = 0;
@@ -258,7 +263,7 @@
} else {
// Use sscanf to parse the individual parts of the command line. At the
// moment no command expects more than two parameters.
- int args = SScanF(line,
+ int argc = SScanF(line,
"%" XSTR(COMMAND_SIZE) "s "
"%" XSTR(ARG_SIZE) "s "
"%" XSTR(ARG_SIZE) "s",
@@ -271,7 +276,7 @@
// Leave the debugger shell.
done = true;
} else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
- if (args == 2) {
+ if (argc == 2) {
int32_t value;
float svalue;
double dvalue;
@@ -296,7 +301,7 @@
}
} else if ((strcmp(cmd, "po") == 0)
|| (strcmp(cmd, "printobject") == 0)) {
- if (args == 2) {
+ if (argc == 2) {
int32_t value;
if (GetValue(arg1, &value)) {
Object* obj = reinterpret_cast<Object*>(value);
@@ -313,6 +318,37 @@
} else {
PrintF("printobject <value>\n");
}
+ } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
+ int32_t* cur = NULL;
+ int32_t* end = NULL;
+ int next_arg = 1;
+
+ if (strcmp(cmd, "stack") == 0) {
+ cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp));
+ } else { // "mem"
+ int32_t value;
+ if (!GetValue(arg1, &value)) {
+ PrintF("%s unrecognized\n", arg1);
+ continue;
+ }
+ cur = reinterpret_cast<int32_t*>(value);
+ next_arg++;
+ }
+
+ int32_t words;
+ if (argc == next_arg) {
+ words = 10;
+ } else if (argc == next_arg + 1) {
+ if (!GetValue(argv[next_arg], &words)) {
+ words = 10;
+ }
+ }
+ end = cur + words;
+
+ while (cur < end) {
+ PrintF(" 0x%08x: 0x%08x %10d\n", cur, *cur, *cur);
+ cur++;
+ }
} else if (strcmp(cmd, "disasm") == 0) {
disasm::NameConverter converter;
disasm::Disassembler dasm(converter);
@@ -322,10 +358,10 @@
byte* cur = NULL;
byte* end = NULL;
- if (args == 1) {
+ if (argc == 1) {
cur = reinterpret_cast<byte*>(sim_->get_pc());
end = cur + (10 * Instr::kInstrSize);
- } else if (args == 2) {
+ } else if (argc == 2) {
int32_t value;
if (GetValue(arg1, &value)) {
cur = reinterpret_cast<byte*>(value);
@@ -351,7 +387,7 @@
v8::internal::OS::DebugBreak();
PrintF("regaining control from gdb\n");
} else if (strcmp(cmd, "break") == 0) {
- if (args == 2) {
+ if (argc == 2) {
int32_t value;
if (GetValue(arg1, &value)) {
if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) {
@@ -401,6 +437,10 @@
PrintF(" print an object from a register (alias 'po')\n");
PrintF("flags\n");
PrintF(" print flags\n");
+ PrintF("stack [<words>]\n");
+ PrintF(" dump stack content, default dump 10 words)\n");
+ PrintF("mem <address> [<words>]\n");
+ PrintF(" dump memory content, default dump 10 words)\n");
PrintF("disasm [<instructions>]\n");
PrintF("disasm [[<address>] <instructions>]\n");
PrintF(" disassemble code, default is 10 instructions from pc\n");
@@ -414,7 +454,7 @@
PrintF(" ignore the stop instruction at the current location");
PrintF(" from now on\n");
PrintF("trace (alias 't')\n");
- PrintF(" toogle the tracing of all executed statements");
+ PrintF(" toogle the tracing of all executed statements\n");
} else {
PrintF("Unknown command: %s\n", cmd);
}
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index bbffef2..62b0373 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -1389,6 +1389,36 @@
}
+Object* LoadStubCompiler::CompileLoadNonexistent(JSObject* object) {
+ // ----------- S t a t e -------------
+ // -- r2 : name
+ // -- lr : return address
+ // -- [sp] : receiver
+ // -----------------------------------
+ Label miss;
+
+ // Load receiver.
+ __ ldr(r0, MemOperand(sp, 0));
+
+ // Check the maps of the full prototype chain.
+ JSObject* last = object;
+ while (last->GetPrototype() != Heap::null_value()) {
+ last = JSObject::cast(last->GetPrototype());
+ }
+ CheckPrototypes(object, r0, last, r3, r1, Heap::empty_string(), &miss);
+
+ // Return undefined if maps of the full prototype chain is still the same.
+ __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
+ __ Ret();
+
+ __ bind(&miss);
+ GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+ // Return the generated code.
+ return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
+
Object* LoadStubCompiler::CompileLoadField(JSObject* object,
JSObject* holder,
int index,
diff --git a/src/array.js b/src/array.js
index c1ba3c3..54d7e57 100644
--- a/src/array.js
+++ b/src/array.js
@@ -649,29 +649,16 @@
function InsertionSortWithFunc(a, from, to) {
for (var i = from + 1; i < to; i++) {
var element = a[i];
- // place element in a[from..i[
- // binary search
- var min = from;
- var max = i;
- // The search interval is a[min..max[
- while (min < max) {
- var mid = min + ((max - min) >> 1);
- var order = %_CallFunction(global_receiver, a[mid], element, comparefn);
- if (order == 0) {
- min = max = mid;
+ for (var j = i - 1; j >= from; j--) {
+ var tmp = a[j];
+ var order = %_CallFunction(global_receiver, tmp, element, comparefn);
+ if (order > 0) {
+ a[j + 1] = tmp;
+ } else {
break;
}
- if (order < 0) {
- min = mid + 1;
- } else {
- max = mid;
- }
}
- // place element at position min==max.
- for (var j = i; j > min; j--) {
- a[j] = a[j - 1];
- }
- a[min] = element;
+ a[j + 1] = element;
}
}
@@ -712,8 +699,6 @@
}
function Compare(x,y) {
- // Assume the comparefn, if any, is a consistent comparison function.
- // If it isn't, we are allowed arbitrary behavior by ECMA 15.4.4.11.
if (x === y) return 0;
if (%_IsSmi(x) && %_IsSmi(y)) {
return %SmiLexicographicCompare(x, y);
@@ -727,32 +712,17 @@
function InsertionSort(a, from, to) {
for (var i = from + 1; i < to; i++) {
var element = a[i];
- // Pre-convert the element to a string for comparison if we know
- // it will happen on each compare anyway.
var key = %_IsSmi(element) ? element : ToString(element);
- // place element in a[from..i[
- // binary search
- var min = from;
- var max = i;
- // The search interval is a[min..max[
- while (min < max) {
- var mid = min + ((max - min) >> 1);
- var order = Compare(a[mid], key);
- if (order == 0) {
- min = max = mid;
+ for (var j = i - 1; j >= from; j--) {
+ var tmp = a[j];
+ var order = Compare(tmp, key);
+ if (order > 0) {
+ a[j + 1] = tmp;
+ } else {
break;
}
- if (order < 0) {
- min = mid + 1;
- } else {
- max = mid;
- }
}
- // place element at position min==max.
- for (var j = i; j > min; j--) {
- a[j] = a[j - 1];
- }
- a[min] = element;
+ a[j + 1] = element;
}
}
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 82a63f0..d88c8e7 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1237,6 +1237,62 @@
apply->shared()->set_length(2);
}
+ // Create a constructor for RegExp results (a variant of Array that
+ // predefines the two properties index and match).
+ {
+ // RegExpResult initial map.
+
+ // Find global.Array.prototype to inherit from.
+ Handle<JSFunction> array_constructor(global_context()->array_function());
+ Handle<JSObject> array_prototype(
+ JSObject::cast(array_constructor->instance_prototype()));
+
+ // Add initial map.
+ Handle<Map> initial_map =
+ Factory::NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
+ initial_map->set_constructor(*array_constructor);
+
+ // Set prototype on map.
+ initial_map->set_non_instance_prototype(false);
+ initial_map->set_prototype(*array_prototype);
+
+ // Update map with length accessor from Array and add "index" and "input".
+ Handle<Map> array_map(global_context()->js_array_map());
+ Handle<DescriptorArray> array_descriptors(
+ array_map->instance_descriptors());
+ ASSERT_EQ(1, array_descriptors->number_of_descriptors());
+
+ Handle<DescriptorArray> reresult_descriptors =
+ Factory::NewDescriptorArray(3);
+
+ reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
+
+ int enum_index = 0;
+ {
+ FieldDescriptor index_field(Heap::index_symbol(),
+ JSRegExpResult::kIndexIndex,
+ NONE,
+ enum_index++);
+ reresult_descriptors->Set(1, &index_field);
+ }
+
+ {
+ FieldDescriptor input_field(Heap::input_symbol(),
+ JSRegExpResult::kInputIndex,
+ NONE,
+ enum_index++);
+ reresult_descriptors->Set(2, &input_field);
+ }
+ reresult_descriptors->Sort();
+
+ initial_map->set_inobject_properties(2);
+ initial_map->set_pre_allocated_property_fields(2);
+ initial_map->set_unused_property_fields(0);
+ initial_map->set_instance_descriptors(*reresult_descriptors);
+
+ global_context()->set_regexp_result_map(*initial_map);
+ }
+
#ifdef DEBUG
builtins->Verify();
#endif
diff --git a/src/circular-queue-inl.h b/src/circular-queue-inl.h
index 962b069..90ab0f5 100644
--- a/src/circular-queue-inl.h
+++ b/src/circular-queue-inl.h
@@ -38,7 +38,8 @@
CircularQueue<Record>::CircularQueue(int desired_buffer_size_in_bytes)
: buffer_(NewArray<Record>(desired_buffer_size_in_bytes / sizeof(Record))),
buffer_end_(buffer_ + desired_buffer_size_in_bytes / sizeof(Record)),
- enqueue_semaphore_(OS::CreateSemaphore((buffer_end_ - buffer_) - 1)),
+ enqueue_semaphore_(
+ OS::CreateSemaphore(static_cast<int>(buffer_end_ - buffer_) - 1)),
enqueue_pos_(buffer_),
dequeue_pos_(buffer_) {
// To be able to distinguish between a full and an empty queue
diff --git a/src/circular-queue.cc b/src/circular-queue.cc
index a7c2532..af650de 100644
--- a/src/circular-queue.cc
+++ b/src/circular-queue.cc
@@ -58,8 +58,10 @@
// updates of positions by different processor cores.
const int positions_size =
RoundUp(1, kProcessorCacheLineSize) +
- RoundUp(sizeof(ProducerPosition), kProcessorCacheLineSize) +
- RoundUp(sizeof(ConsumerPosition), kProcessorCacheLineSize);
+ RoundUp(static_cast<int>(sizeof(ProducerPosition)),
+ kProcessorCacheLineSize) +
+ RoundUp(static_cast<int>(sizeof(ConsumerPosition)),
+ kProcessorCacheLineSize);
positions_ = NewArray<byte>(positions_size);
producer_pos_ = reinterpret_cast<ProducerPosition*>(
diff --git a/src/codegen.h b/src/codegen.h
index d4518e6..d56d4ee 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -123,6 +123,7 @@
F(SubString, 3, 1) \
F(StringCompare, 2, 1) \
F(RegExpExec, 4, 1) \
+ F(RegExpConstructResult, 3, 1) \
F(NumberToString, 1, 1) \
F(MathPow, 2, 1) \
F(MathSin, 1, 1) \
diff --git a/src/contexts.h b/src/contexts.h
index 44c90b6..ce112f3 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -76,6 +76,7 @@
V(FUNCTION_MAP_INDEX, Map, function_map) \
V(FUNCTION_INSTANCE_MAP_INDEX, Map, function_instance_map) \
V(JS_ARRAY_MAP_INDEX, Map, js_array_map)\
+ V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
@@ -175,6 +176,7 @@
SECURITY_TOKEN_INDEX,
ARGUMENTS_BOILERPLATE_INDEX,
JS_ARRAY_MAP_INDEX,
+ REGEXP_RESULT_MAP_INDEX,
FUNCTION_MAP_INDEX,
FUNCTION_INSTANCE_MAP_INDEX,
INITIAL_OBJECT_PROTOTYPE_INDEX,
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index 2535ce0..335bd2b 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -663,10 +663,28 @@
}
+Handle<Value> Shell::UnsetEnvironment(const Arguments& args) {
+ if (args.Length() != 1) {
+ const char* message = "unsetenv() takes one argument";
+ return ThrowException(String::New(message));
+ }
+ String::Utf8Value var(args[0]);
+ if (*var == NULL) {
+ const char* message =
+ "os.setenv(): String conversion of variable name failed.";
+ return ThrowException(String::New(message));
+ }
+ unsetenv(*var);
+ return v8::Undefined();
+}
+
+
void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) {
os_templ->Set(String::New("system"), FunctionTemplate::New(System));
os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory));
os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment));
+ os_templ->Set(String::New("unsetenv"),
+ FunctionTemplate::New(UnsetEnvironment));
os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask));
os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory));
os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory));
diff --git a/src/d8.h b/src/d8.h
index c93ea46..9df291b 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -175,6 +175,7 @@
static Handle<Value> System(const Arguments& args);
static Handle<Value> ChangeDirectory(const Arguments& args);
static Handle<Value> SetEnvironment(const Arguments& args);
+ static Handle<Value> UnsetEnvironment(const Arguments& args);
static Handle<Value> SetUMask(const Arguments& args);
static Handle<Value> MakeDirectory(const Arguments& args);
static Handle<Value> RemoveDirectory(const Arguments& args);
diff --git a/src/execution.cc b/src/execution.cc
index 2068413..e8b0d94 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -221,8 +221,8 @@
void StackGuard::EnableInterrupts() {
ExecutionAccess access;
- if (IsSet(access)) {
- set_limits(kInterruptLimit, access);
+ if (has_pending_interrupts(access)) {
+ set_interrupt_limits(access);
}
}
@@ -249,11 +249,6 @@
}
-bool StackGuard::IsSet(const ExecutionAccess& lock) {
- return thread_local_.interrupt_flags_ != 0;
-}
-
-
bool StackGuard::IsInterrupted() {
ExecutionAccess access;
return thread_local_.interrupt_flags_ & INTERRUPT;
@@ -263,7 +258,7 @@
void StackGuard::Interrupt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= INTERRUPT;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
@@ -276,7 +271,7 @@
void StackGuard::Preempt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= PREEMPT;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
@@ -289,7 +284,7 @@
void StackGuard::TerminateExecution() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= TERMINATE;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
@@ -303,7 +298,7 @@
void StackGuard::DebugBreak() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGBREAK;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
@@ -317,7 +312,7 @@
if (FLAG_debugger_auto_break) {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limits(access);
}
}
#endif
@@ -325,7 +320,7 @@
void StackGuard::Continue(InterruptFlag after_what) {
ExecutionAccess access;
thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
- if (thread_local_.interrupt_flags_ == 0) {
+ if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
reset_limits(access);
}
}
diff --git a/src/execution.h b/src/execution.h
index 10683d6..e683e12 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -199,12 +199,24 @@
private:
// You should hold the ExecutionAccess lock when calling this method.
- static bool IsSet(const ExecutionAccess& lock);
+ static bool has_pending_interrupts(const ExecutionAccess& lock) {
+ // Sanity check: We shouldn't be asking about pending interrupts
+ // unless we're not postponing them anymore.
+ ASSERT(!should_postpone_interrupts(lock));
+ return thread_local_.interrupt_flags_ != 0;
+ }
// You should hold the ExecutionAccess lock when calling this method.
- static void set_limits(uintptr_t value, const ExecutionAccess& lock) {
- thread_local_.jslimit_ = value;
- thread_local_.climit_ = value;
+ static bool should_postpone_interrupts(const ExecutionAccess& lock) {
+ return thread_local_.postpone_interrupts_nesting_ > 0;
+ }
+
+ // You should hold the ExecutionAccess lock when calling this method.
+ static void set_interrupt_limits(const ExecutionAccess& lock) {
+ // Ignore attempts to interrupt when interrupts are postponed.
+ if (should_postpone_interrupts(lock)) return;
+ thread_local_.jslimit_ = kInterruptLimit;
+ thread_local_.climit_ = kInterruptLimit;
Heap::SetStackLimits();
}
diff --git a/src/globals.h b/src/globals.h
index 3d48e2d..410cb3f 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -428,7 +428,11 @@
CONSTANT_TRANSITION = 6, // only in fast mode
NULL_DESCRIPTOR = 7, // only in fast mode
// All properties before MAP_TRANSITION are real.
- FIRST_PHANTOM_PROPERTY_TYPE = MAP_TRANSITION
+ FIRST_PHANTOM_PROPERTY_TYPE = MAP_TRANSITION,
+ // There are no IC stubs for NULL_DESCRIPTORS. Therefore,
+ // NULL_DESCRIPTOR can be used as the type flag for IC stubs for
+ // nonexistent properties.
+ NONEXISTENT = NULL_DESCRIPTOR
};
diff --git a/src/heap-inl.h b/src/heap-inl.h
index ba4850e..bf9c535 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -240,6 +240,27 @@
}
+void Heap::MoveBlock(Object** dst, Object** src, size_t byte_size) {
+ ASSERT(IsAligned<size_t>(byte_size, kPointerSize));
+
+ int size_in_words = byte_size / kPointerSize;
+
+ if ((dst < src) || (dst >= (src + size_in_words))) {
+ ASSERT((dst >= (src + size_in_words)) ||
+ ((OffsetFrom(reinterpret_cast<Address>(src)) -
+ OffsetFrom(reinterpret_cast<Address>(dst))) >= kPointerSize));
+
+ Object** end = src + size_in_words;
+
+ while (src != end) {
+ *dst++ = *src++;
+ }
+ } else {
+ memmove(dst, src, byte_size);
+ }
+}
+
+
void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
ASSERT(InFromSpace(object));
diff --git a/src/heap.cc b/src/heap.cc
index 4693e40..7a5188f 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -562,23 +562,18 @@
EnsureFromSpaceIsCommitted();
- // Perform mark-sweep with optional compaction.
if (collector == MARK_COMPACTOR) {
+ // Perform mark-sweep with optional compaction.
MarkCompact(tracer);
- }
- // Always perform a scavenge to make room in new space.
- Scavenge();
-
- // Update the old space promotion limits after the scavenge due to
- // promotions during scavenge.
- if (collector == MARK_COMPACTOR) {
int old_gen_size = PromotedSpaceSize();
old_gen_promotion_limit_ =
old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
old_gen_allocation_limit_ =
old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
old_gen_exhausted_ = false;
+ } else {
+ Scavenge();
}
Counters::objs_since_last_young.Set(0);
@@ -764,6 +759,17 @@
#endif
+void Heap::CheckNewSpaceExpansionCriteria() {
+ if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
+ survived_since_last_expansion_ > new_space_.Capacity()) {
+ // Grow the size of new space if there is room to grow and enough
+ // data has survived scavenge since the last expansion.
+ new_space_.Grow();
+ survived_since_last_expansion_ = 0;
+ }
+}
+
+
void Heap::Scavenge() {
#ifdef DEBUG
if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers();
@@ -780,13 +786,7 @@
// Used for updating survived_since_last_expansion_ at function end.
int survived_watermark = PromotedSpaceSize();
- if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
- survived_since_last_expansion_ > new_space_.Capacity()) {
- // Grow the size of new space if there is room to grow and enough
- // data has survived scavenge since the last expansion.
- new_space_.Grow();
- survived_since_last_expansion_ = 0;
- }
+ CheckNewSpaceExpansionCriteria();
// Flip the semispaces. After flipping, to space is empty, from space has
// live objects.
@@ -837,15 +837,17 @@
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
- ScavengeExternalStringTable();
+ UpdateNewSpaceReferencesInExternalStringTable(
+ &UpdateNewSpaceReferenceInExternalStringTableEntry);
+
ASSERT(new_space_front == new_space_.top());
// Set age mark.
new_space_.set_age_mark(new_space_.top());
// Update how much has survived scavenge.
- survived_since_last_expansion_ +=
- (PromotedSpaceSize() - survived_watermark) + new_space_.Size();
+ IncrementYoungSurvivorsCounter(
+ (PromotedSpaceSize() - survived_watermark) + new_space_.Size());
LOG(ResourceEvent("scavenge", "end"));
@@ -853,7 +855,22 @@
}
-void Heap::ScavengeExternalStringTable() {
+String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Object** p) {
+ MapWord first_word = HeapObject::cast(*p)->map_word();
+
+ if (!first_word.IsForwardingAddress()) {
+ // Unreachable external string can be finalized.
+ FinalizeExternalString(String::cast(*p));
+ return NULL;
+ }
+
+ // String is still reachable.
+ return String::cast(first_word.ToForwardingAddress());
+}
+
+
+void Heap::UpdateNewSpaceReferencesInExternalStringTable(
+ ExternalStringTableUpdaterCallback updater_func) {
ExternalStringTable::Verify();
if (ExternalStringTable::new_space_strings_.is_empty()) return;
@@ -864,16 +881,10 @@
for (Object** p = start; p < end; ++p) {
ASSERT(Heap::InFromSpace(*p));
- MapWord first_word = HeapObject::cast(*p)->map_word();
+ String* target = updater_func(p);
- if (!first_word.IsForwardingAddress()) {
- // Unreachable external string can be finalized.
- FinalizeExternalString(String::cast(*p));
- continue;
- }
+ if (target == NULL) continue;
- // String is still reachable.
- String* target = String::cast(first_word.ToForwardingAddress());
ASSERT(target->IsExternalString());
if (Heap::InNewSpace(target)) {
@@ -1487,10 +1498,9 @@
}
-Object* Heap::CreateOddball(Map* map,
- const char* to_string,
+Object* Heap::CreateOddball(const char* to_string,
Object* to_number) {
- Object* result = Allocate(map, OLD_DATA_SPACE);
+ Object* result = Allocate(oddball_map(), OLD_DATA_SPACE);
if (result->IsFailure()) return result;
return Oddball::cast(result)->Initialize(to_string, to_number);
}
@@ -1594,34 +1604,27 @@
Oddball::cast(undefined_value())->set_to_string(String::cast(symbol));
Oddball::cast(undefined_value())->set_to_number(nan_value());
- // Assign the print strings for oddballs after creating symboltable.
- symbol = LookupAsciiSymbol("null");
- if (symbol->IsFailure()) return false;
- Oddball::cast(null_value())->set_to_string(String::cast(symbol));
- Oddball::cast(null_value())->set_to_number(Smi::FromInt(0));
-
// Allocate the null_value
obj = Oddball::cast(null_value())->Initialize("null", Smi::FromInt(0));
if (obj->IsFailure()) return false;
- obj = CreateOddball(oddball_map(), "true", Smi::FromInt(1));
+ obj = CreateOddball("true", Smi::FromInt(1));
if (obj->IsFailure()) return false;
set_true_value(obj);
- obj = CreateOddball(oddball_map(), "false", Smi::FromInt(0));
+ obj = CreateOddball("false", Smi::FromInt(0));
if (obj->IsFailure()) return false;
set_false_value(obj);
- obj = CreateOddball(oddball_map(), "hole", Smi::FromInt(-1));
+ obj = CreateOddball("hole", Smi::FromInt(-1));
if (obj->IsFailure()) return false;
set_the_hole_value(obj);
- obj = CreateOddball(
- oddball_map(), "no_interceptor_result_sentinel", Smi::FromInt(-2));
+ obj = CreateOddball("no_interceptor_result_sentinel", Smi::FromInt(-2));
if (obj->IsFailure()) return false;
set_no_interceptor_result_sentinel(obj);
- obj = CreateOddball(oddball_map(), "termination_exception", Smi::FromInt(-3));
+ obj = CreateOddball("termination_exception", Smi::FromInt(-3));
if (obj->IsFailure()) return false;
set_termination_exception(obj);
@@ -2315,7 +2318,8 @@
Address old_addr = code->address();
- int relocation_offset = code->relocation_start() - old_addr;
+ size_t relocation_offset =
+ static_cast<size_t>(code->relocation_start() - old_addr);
Object* result;
if (new_obj_size > MaxObjectSizeInPagedSpace()) {
diff --git a/src/heap.h b/src/heap.h
index 3b1d3ce..fbd77ff 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -153,6 +153,8 @@
V(global_symbol, "global") \
V(ignore_case_symbol, "ignoreCase") \
V(multiline_symbol, "multiline") \
+ V(input_symbol, "input") \
+ V(index_symbol, "index") \
V(last_index_symbol, "lastIndex") \
V(object_symbol, "object") \
V(prototype_symbol, "prototype") \
@@ -200,6 +202,9 @@
class HeapStats;
+typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer);
+
+
// The all static Heap captures the interface to the global object heap.
// All JavaScript contexts by this process share the same object heap.
@@ -944,6 +949,30 @@
static void RecordStats(HeapStats* stats);
+ // Copy block of memory from src to dst. Size of block should be aligned
+ // by pointer size.
+ static inline void CopyBlock(Object** dst, Object** src, int byte_size);
+
+ // Optimized version of memmove for blocks with pointer size aligned sizes and
+ // pointer size aligned addresses.
+ static inline void MoveBlock(Object** dst, Object** src, size_t byte_size);
+
+ // Check new space expansion criteria and expand semispaces if it was hit.
+ static void CheckNewSpaceExpansionCriteria();
+
+ static inline void IncrementYoungSurvivorsCounter(int survived) {
+ survived_since_last_expansion_ += survived;
+ }
+
+ static void UpdateNewSpaceReferencesInExternalStringTable(
+ ExternalStringTableUpdaterCallback updater_func);
+
+ // Helper function that governs the promotion policy from new space to
+ // old. If the object's old address lies below the new space's age
+ // mark or if we've already filled the bottom 1/16th of the to space,
+ // we try to promote this object.
+ static inline bool ShouldBePromoted(Address old_address, int object_size);
+
static int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; }
private:
@@ -1131,16 +1160,17 @@
static void CreateFixedStubs();
- static Object* CreateOddball(Map* map,
- const char* to_string,
- Object* to_number);
+ static Object* CreateOddball(const char* to_string, Object* to_number);
// Allocate empty fixed array.
static Object* AllocateEmptyFixedArray();
// Performs a minor collection in new generation.
static void Scavenge();
- static void ScavengeExternalStringTable();
+
+ static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
+ Object** pointer);
+
static Address DoScavenge(ObjectVisitor* scavenge_visitor,
Address new_space_front);
@@ -1158,11 +1188,6 @@
HeapObject* target,
int size);
- // Helper function that governs the promotion policy from new space to
- // old. If the object's old address lies below the new space's age
- // mark or if we've already filled the bottom 1/16th of the to space,
- // we try to promote this object.
- static inline bool ShouldBePromoted(Address old_address, int object_size);
#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
// Record the copy of an object in the NewSpace's statistics.
static void RecordCopiedObject(HeapObject* obj);
@@ -1181,9 +1206,6 @@
// Slow part of scavenge object.
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
- // Copy memory from src to dst.
- static inline void CopyBlock(Object** dst, Object** src, int byte_size);
-
// Initializes a function with a shared part and prototype.
// Returns the function.
// Note: this code was factored out of AllocateFunction such that
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index bbbcd3a..bac4ee5 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -2432,7 +2432,8 @@
left_side_constant_null = left_side.handle()->IsNull();
left_side_constant_1_char_string =
(left_side.handle()->IsString() &&
- (String::cast(*left_side.handle())->length() == 1));
+ String::cast(*left_side.handle())->length() == 1 &&
+ String::cast(*left_side.handle())->IsAsciiRepresentation());
}
bool right_side_constant_smi = false;
bool right_side_constant_null = false;
@@ -2442,7 +2443,8 @@
right_side_constant_null = right_side.handle()->IsNull();
right_side_constant_1_char_string =
(right_side.handle()->IsString() &&
- (String::cast(*right_side.handle())->length() == 1));
+ String::cast(*right_side.handle())->length() == 1 &&
+ String::cast(*right_side.handle())->IsAsciiRepresentation());
}
if (left_side_constant_smi || right_side_constant_smi) {
@@ -2631,6 +2633,7 @@
JumpTarget is_not_string, is_string;
Register left_reg = left_side.reg();
Handle<Object> right_val = right_side.handle();
+ ASSERT(StringShape(String::cast(*right_val)).IsSymbol());
__ test(left_side.reg(), Immediate(kSmiTagMask));
is_not_string.Branch(zero, &left_side);
Result temp = allocator_->Allocate();
@@ -2655,7 +2658,7 @@
dest->false_target()->Branch(not_equal);
__ bind(¬_a_symbol);
}
- // If the receiver is not a string of the type we handle call the stub.
+ // Call the compare stub if the left side is not a flat ascii string.
__ and_(temp.reg(),
kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
__ cmp(temp.reg(), kStringTag | kSeqStringTag | kAsciiStringTag);
@@ -2673,7 +2676,7 @@
dest->false_target()->Jump();
is_string.Bind(&left_side);
- // Here we know we have a sequential ASCII string.
+ // left_side is a sequential ASCII string.
left_side = Result(left_reg);
right_side = Result(right_val);
Result temp2 = allocator_->Allocate();
@@ -2685,7 +2688,7 @@
Immediate(1));
__ j(not_equal, &comparison_done);
uint8_t char_value =
- static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
+ static_cast<uint8_t>(String::cast(*right_val)->Get(0));
__ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
char_value);
__ bind(&comparison_done);
@@ -2694,17 +2697,17 @@
FieldOperand(left_side.reg(), String::kLengthOffset));
__ sub(Operand(temp2.reg()), Immediate(1));
Label comparison;
- // If the length is 0 then our subtraction gave -1 which compares less
+ // If the length is 0 then the subtraction gave -1 which compares less
// than any character.
__ j(negative, &comparison);
// Otherwise load the first character.
__ movzx_b(temp2.reg(),
FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize));
__ bind(&comparison);
- // Compare the first character of the string with out constant
- // 1-character string.
+ // Compare the first character of the string with the
+ // constant 1-character string.
uint8_t char_value =
- static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
+ static_cast<uint8_t>(String::cast(*right_val)->Get(0));
__ cmp(Operand(temp2.reg()), Immediate(char_value));
Label characters_were_different;
__ j(not_equal, &characters_were_different);
@@ -6523,7 +6526,7 @@
void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
- ASSERT_EQ(args->length(), 4);
+ ASSERT_EQ(4, args->length());
// Load the arguments on the stack and call the stub.
Load(args->at(0));
@@ -6536,6 +6539,95 @@
}
+void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
+ // No stub. This code only occurs a few times in regexp.js.
+ const int kMaxInlineLength = 100;
+ ASSERT_EQ(3, args->length());
+ Load(args->at(0)); // Size of array, smi.
+ Load(args->at(1)); // "index" property value.
+ Load(args->at(2)); // "input" property value.
+ {
+ VirtualFrame::SpilledScope spilled_scope;
+
+ Label slowcase;
+ Label done;
+ __ mov(ebx, Operand(esp, kPointerSize * 2));
+ __ test(ebx, Immediate(kSmiTagMask));
+ __ j(not_zero, &slowcase);
+ __ cmp(Operand(ebx), Immediate(Smi::FromInt(kMaxInlineLength)));
+ __ j(above, &slowcase);
+ // Smi-tagging is equivalent to multiplying by 2.
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+ // Allocate RegExpResult followed by FixedArray with size in ebx.
+ // JSArray: [Map][empty properties][Elements][Length-smi][index][input]
+ // Elements: [Map][Length][..elements..]
+ __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+ times_half_pointer_size,
+ ebx, // In: Number of elements (times 2, being a smi)
+ eax, // Out: Start of allocation (tagged).
+ ecx, // Out: End of allocation.
+ edx, // Scratch register
+ &slowcase,
+ TAG_OBJECT);
+ // eax: Start of allocated area, object-tagged.
+
+ // Set JSArray map to global.regexp_result_map().
+ // Set empty properties FixedArray.
+ // Set elements to point to FixedArray allocated right after the JSArray.
+ // Interleave operations for better latency.
+ __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
+ __ mov(ecx, Immediate(Factory::empty_fixed_array()));
+ __ lea(ebx, Operand(eax, JSRegExpResult::kSize));
+ __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
+ __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
+ __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
+ __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX));
+ __ mov(FieldOperand(eax, HeapObject::kMapOffset), edx);
+
+ // Set input, index and length fields from arguments.
+ __ pop(FieldOperand(eax, JSRegExpResult::kInputOffset));
+ __ pop(FieldOperand(eax, JSRegExpResult::kIndexOffset));
+ __ pop(ecx);
+ __ mov(FieldOperand(eax, JSArray::kLengthOffset), ecx);
+
+ // Fill out the elements FixedArray.
+ // eax: JSArray.
+ // ebx: FixedArray.
+ // ecx: Number of elements in array, as smi.
+
+ // Set map.
+ __ mov(FieldOperand(ebx, HeapObject::kMapOffset),
+ Immediate(Factory::fixed_array_map()));
+ // Set length.
+ __ SmiUntag(ecx);
+ __ mov(FieldOperand(ebx, FixedArray::kLengthOffset), ecx);
+ // Fill contents of fixed-array with the-hole.
+ __ mov(edx, Immediate(Factory::the_hole_value()));
+ __ lea(ebx, FieldOperand(ebx, FixedArray::kHeaderSize));
+ // Fill fixed array elements with hole.
+ // eax: JSArray.
+ // ecx: Number of elements to fill.
+ // ebx: Start of elements in FixedArray.
+ // edx: the hole.
+ Label loop;
+ __ test(ecx, Operand(ecx));
+ __ bind(&loop);
+ __ j(less_equal, &done); // Jump if ecx is negative or zero.
+ __ sub(Operand(ecx), Immediate(1));
+ __ mov(Operand(ebx, ecx, times_pointer_size, 0), edx);
+ __ jmp(&loop);
+
+ __ bind(&slowcase);
+ __ CallRuntime(Runtime::kRegExpConstructResult, 3);
+
+ __ bind(&done);
+ }
+ frame_->Forget(3);
+ frame_->Push(eax);
+}
+
+
void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
@@ -11082,62 +11174,94 @@
}
+static int NegativeComparisonResult(Condition cc) {
+ ASSERT(cc != equal);
+ ASSERT((cc == less) || (cc == less_equal)
+ || (cc == greater) || (cc == greater_equal));
+ return (cc == greater || cc == greater_equal) ? LESS : GREATER;
+}
+
+
void CompareStub::Generate(MacroAssembler* masm) {
Label call_builtin, done;
// NOTICE! This code is only reached after a smi-fast-case check, so
// it is certain that at least one operand isn't a smi.
- if (cc_ == equal) { // Both strict and non-strict.
- Label slow; // Fallthrough label.
- // Equality is almost reflexive (everything but NaN), so start by testing
- // for "identity and not NaN".
- {
- Label not_identical;
- __ cmp(eax, Operand(edx));
- __ j(not_equal, ¬_identical);
- // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
- // so we do the second best thing - test it ourselves.
+ // Identical objects can be compared fast, but there are some tricky cases
+ // for NaN and undefined.
+ {
+ Label not_identical;
+ __ cmp(eax, Operand(edx));
+ __ j(not_equal, ¬_identical);
- if (never_nan_nan_) {
- __ Set(eax, Immediate(0));
- __ ret(0);
- } else {
- Label return_equal;
- Label heap_number;
- // If it's not a heap number, then return equal.
- __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(Factory::heap_number_map()));
- __ j(equal, &heap_number);
- __ bind(&return_equal);
- __ Set(eax, Immediate(0));
- __ ret(0);
+ if (cc_ != equal) {
+ // Check for undefined. undefined OP undefined is false even though
+ // undefined == undefined.
+ Label check_for_nan;
+ __ cmp(edx, Factory::undefined_value());
+ __ j(not_equal, &check_for_nan);
+ __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
+ __ ret(0);
+ __ bind(&check_for_nan);
+ }
- __ bind(&heap_number);
- // It is a heap number, so return non-equal if it's NaN and equal if
- // it's not NaN.
- // The representation of NaN values has all exponent bits (52..62) set,
- // and not all mantissa bits (0..51) clear.
- // We only accept QNaNs, which have bit 51 set.
- // Read top bits of double representation (second word of value).
+ // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
+ // so we do the second best thing - test it ourselves.
+ // Note: if cc_ != equal, never_nan_nan_ is not used.
+ if (never_nan_nan_ && (cc_ == equal)) {
+ __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
+ __ ret(0);
+ } else {
+ Label return_equal;
+ Label heap_number;
+ // If it's not a heap number, then return equal.
+ __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
+ Immediate(Factory::heap_number_map()));
+ __ j(equal, &heap_number);
+ __ bind(&return_equal);
+ __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
+ __ ret(0);
- // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
- // all bits in the mask are set. We only need to check the word
- // that contains the exponent and high bit of the mantissa.
- ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
- __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
- __ xor_(eax, Operand(eax));
- // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
- // bits.
- __ add(edx, Operand(edx));
- __ cmp(edx, kQuietNaNHighBitsMask << 1);
+ __ bind(&heap_number);
+ // It is a heap number, so return non-equal if it's NaN and equal if
+ // it's not NaN.
+ // The representation of NaN values has all exponent bits (52..62) set,
+ // and not all mantissa bits (0..51) clear.
+ // We only accept QNaNs, which have bit 51 set.
+ // Read top bits of double representation (second word of value).
+
+ // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
+ // all bits in the mask are set. We only need to check the word
+ // that contains the exponent and high bit of the mantissa.
+ ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
+ __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
+ __ xor_(eax, Operand(eax));
+ // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
+ // bits.
+ __ add(edx, Operand(edx));
+ __ cmp(edx, kQuietNaNHighBitsMask << 1);
+ if (cc_ == equal) {
+ ASSERT_NE(1, EQUAL);
__ setcc(above_equal, eax);
__ ret(0);
+ } else {
+ Label nan;
+ __ j(above_equal, &nan);
+ __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
+ __ ret(0);
+ __ bind(&nan);
+ __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
+ __ ret(0);
}
-
- __ bind(¬_identical);
}
+ __ bind(¬_identical);
+ }
+
+ if (cc_ == equal) { // Both strict and non-strict.
+ Label slow; // Fallthrough label.
+
// If we're doing a strict equality comparison, we don't have to do
// type conversion, so we generate code to do fast comparison for objects
// and oddballs. Non-smi numbers and strings still go through the usual
@@ -11327,14 +11451,7 @@
builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
builtin = Builtins::COMPARE;
- int ncr; // NaN compare result
- if (cc_ == less || cc_ == less_equal) {
- ncr = GREATER;
- } else {
- ASSERT(cc_ == greater || cc_ == greater_equal); // remaining cases
- ncr = LESS;
- }
- __ push(Immediate(Smi::FromInt(ncr)));
+ __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
}
// Restore return address on the stack.
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 03a0fba..a8568f0 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -628,6 +628,8 @@
// Support for direct calls from JavaScript to native RegExp code.
void GenerateRegExpExec(ZoneList<Expression*>* args);
+ void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
+
// Fast support for number to string.
void GenerateNumberToString(ZoneList<Expression*>* args);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 315600b..396a5a3 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1948,6 +1948,32 @@
}
+Object* LoadStubCompiler::CompileLoadNonexistent(JSObject* object) {
+ // ----------- S t a t e -------------
+ // -- eax : receiver
+ // -- ecx : name
+ // -- esp[0] : return address
+ // -----------------------------------
+ Label miss;
+
+ // Check the maps of the full prototype chain.
+ JSObject* last = object;
+ while (last->GetPrototype() != Heap::null_value()) {
+ last = JSObject::cast(last->GetPrototype());
+ }
+ CheckPrototypes(object, eax, last, ebx, edx, Heap::empty_string(), &miss);
+
+ // Return undefined if maps of the full prototype chain is still the same.
+ __ mov(eax, Factory::undefined_value());
+ __ ret(0);
+
+ __ bind(&miss);
+ GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+ // Return the generated code.
+ return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
Object* LoadStubCompiler::CompileLoadField(JSObject* object,
JSObject* holder,
diff --git a/src/ic.cc b/src/ic.cc
index b9ca00f..410699c 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -694,8 +694,8 @@
State state,
Handle<Object> object,
Handle<String> name) {
- // Bail out if we didn't find a result.
- if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
+ // Bail out if the result is not cachable.
+ if (!lookup->IsCacheable()) return;
// Loading properties from values is not common, so don't try to
// deal with non-JS objects here.
@@ -709,6 +709,9 @@
// Set the target to the pre monomorphic stub to delay
// setting the monomorphic state.
code = pre_monomorphic_stub();
+ } else if (!lookup->IsProperty()) {
+ // Nonexistent property. The result is undefined.
+ code = StubCache::ComputeLoadNonexistent(*name, *receiver);
} else {
// Compute monomorphic stub.
switch (lookup->type()) {
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 8e02b5d..8c1316b 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -558,8 +558,9 @@
Vector<byte> GetResult() {
// Return the bytes from pos up to end of buffer.
- return Vector<byte>(reloc_info_writer_.pos(),
- buffer_ + buffer_size_ - reloc_info_writer_.pos());
+ int result_size =
+ static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer_.pos());
+ return Vector<byte>(reloc_info_writer_.pos(), result_size);
}
private:
@@ -581,7 +582,8 @@
byte* new_buffer = NewArray<byte>(new_buffer_size);
// Copy the data.
- int curently_used_size = buffer_ + buffer_size_ - reloc_info_writer_.pos();
+ int curently_used_size =
+ static_cast<int>(buffer_ + buffer_size_ - reloc_info_writer_.pos());
memmove(new_buffer + new_buffer_size - curently_used_size,
reloc_info_writer_.pos(), curently_used_size);
@@ -986,7 +988,7 @@
DropActivationsInActiveThread(shared_info_array, result, do_drop);
if (error_message != NULL) {
// Add error message as an array extra element.
- Vector<const char> vector_message(error_message, strlen(error_message));
+ Vector<const char> vector_message(error_message, StrLength(error_message));
Handle<String> str = Factory::NewStringFromAscii(vector_message);
SetElement(result, len, str);
}
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 2dfe3cc..80ad389 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -53,13 +53,13 @@
// Counters used for debugging the marking phase of mark-compact or mark-sweep
// collection.
int MarkCompactCollector::live_bytes_ = 0;
-int MarkCompactCollector::live_young_objects_ = 0;
-int MarkCompactCollector::live_old_data_objects_ = 0;
-int MarkCompactCollector::live_old_pointer_objects_ = 0;
-int MarkCompactCollector::live_code_objects_ = 0;
-int MarkCompactCollector::live_map_objects_ = 0;
-int MarkCompactCollector::live_cell_objects_ = 0;
-int MarkCompactCollector::live_lo_objects_ = 0;
+int MarkCompactCollector::live_young_objects_size_ = 0;
+int MarkCompactCollector::live_old_data_objects_size_ = 0;
+int MarkCompactCollector::live_old_pointer_objects_size_ = 0;
+int MarkCompactCollector::live_code_objects_size_ = 0;
+int MarkCompactCollector::live_map_objects_size_ = 0;
+int MarkCompactCollector::live_cell_objects_size_ = 0;
+int MarkCompactCollector::live_lo_objects_size_ = 0;
#endif
void MarkCompactCollector::CollectGarbage() {
@@ -136,13 +136,13 @@
#ifdef DEBUG
live_bytes_ = 0;
- live_young_objects_ = 0;
- live_old_pointer_objects_ = 0;
- live_old_data_objects_ = 0;
- live_code_objects_ = 0;
- live_map_objects_ = 0;
- live_cell_objects_ = 0;
- live_lo_objects_ = 0;
+ live_young_objects_size_ = 0;
+ live_old_pointer_objects_size_ = 0;
+ live_old_data_objects_size_ = 0;
+ live_code_objects_size_ = 0;
+ live_map_objects_size_ = 0;
+ live_cell_objects_size_ = 0;
+ live_lo_objects_size_ = 0;
#endif
}
@@ -742,21 +742,21 @@
void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
live_bytes_ += obj->Size();
if (Heap::new_space()->Contains(obj)) {
- live_young_objects_++;
+ live_young_objects_size_ += obj->Size();
} else if (Heap::map_space()->Contains(obj)) {
ASSERT(obj->IsMap());
- live_map_objects_++;
+ live_map_objects_size_ += obj->Size();
} else if (Heap::cell_space()->Contains(obj)) {
ASSERT(obj->IsJSGlobalPropertyCell());
- live_cell_objects_++;
+ live_cell_objects_size_ += obj->Size();
} else if (Heap::old_pointer_space()->Contains(obj)) {
- live_old_pointer_objects_++;
+ live_old_pointer_objects_size_ += obj->Size();
} else if (Heap::old_data_space()->Contains(obj)) {
- live_old_data_objects_++;
+ live_old_data_objects_size_ += obj->Size();
} else if (Heap::code_space()->Contains(obj)) {
- live_code_objects_++;
+ live_code_objects_size_ += obj->Size();
} else if (Heap::lo_space()->Contains(obj)) {
- live_lo_objects_++;
+ live_lo_objects_size_ += obj->Size();
} else {
UNREACHABLE();
}
@@ -1068,31 +1068,210 @@
}
-static void SweepSpace(NewSpace* space) {
+// We scavange new space simultaneously with sweeping. This is done in two
+// passes.
+// The first pass migrates all alive objects from one semispace to another or
+// promotes them to old space. Forwading address is written directly into
+// first word of object without any encoding. If object is dead we are writing
+// NULL as a forwarding address.
+// The second pass updates pointers to new space in all spaces. It is possible
+// to encounter pointers to dead objects during traversal of remembered set for
+// map space because remembered set bits corresponding to dead maps are cleared
+// later during map space sweeping.
+static void MigrateObject(Address dst, Address src, int size) {
+ Heap::CopyBlock(reinterpret_cast<Object**>(dst),
+ reinterpret_cast<Object**>(src),
+ size);
+
+ Memory::Address_at(src) = dst;
+}
+
+
+// Visitor for updating pointers from live objects in old spaces to new space.
+// It does not expect to encounter pointers to dead objects.
+class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
+ public:
+ void VisitPointer(Object** p) {
+ UpdatePointer(p);
+ }
+
+ void VisitPointers(Object** start, Object** end) {
+ for (Object** p = start; p < end; p++) UpdatePointer(p);
+ }
+
+ void VisitCodeTarget(RelocInfo* rinfo) {
+ ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
+ Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ VisitPointer(&target);
+ rinfo->set_target_address(Code::cast(target)->instruction_start());
+ }
+
+ void VisitDebugTarget(RelocInfo* rinfo) {
+ ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) &&
+ rinfo->IsPatchedReturnSequence());
+ Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
+ VisitPointer(&target);
+ rinfo->set_call_address(Code::cast(target)->instruction_start());
+ }
+
+ private:
+ void UpdatePointer(Object** p) {
+ if (!(*p)->IsHeapObject()) return;
+
+ HeapObject* obj = HeapObject::cast(*p);
+ Address old_addr = obj->address();
+
+ if (Heap::new_space()->Contains(obj)) {
+ ASSERT(Heap::InFromSpace(*p));
+ *p = HeapObject::FromAddress(Memory::Address_at(old_addr));
+ }
+ }
+};
+
+// Visitor for updating pointers from live objects in old spaces to new space.
+// It can encounter pointers to dead objects in new space when traversing map
+// space (see comment for MigrateObject).
+static void UpdatePointerToNewGen(HeapObject** p) {
+ if (!(*p)->IsHeapObject()) return;
+
+ Address old_addr = (*p)->address();
+ ASSERT(Heap::InFromSpace(*p));
+
+ Address new_addr = Memory::Address_at(old_addr);
+
+ // Object pointed by *p is dead. Update is not required.
+ if (new_addr == NULL) return;
+
+ *p = HeapObject::FromAddress(new_addr);
+}
+
+
+static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Object **p) {
+ Address old_addr = HeapObject::cast(*p)->address();
+ Address new_addr = Memory::Address_at(old_addr);
+ return String::cast(HeapObject::FromAddress(new_addr));
+}
+
+
+static bool TryPromoteObject(HeapObject* object, int object_size) {
+ Object* result;
+
+ if (object_size > Heap::MaxObjectSizeInPagedSpace()) {
+ result = Heap::lo_space()->AllocateRawFixedArray(object_size);
+ if (!result->IsFailure()) {
+ HeapObject* target = HeapObject::cast(result);
+ MigrateObject(target->address(), object->address(), object_size);
+ Heap::UpdateRSet(target);
+ return true;
+ }
+ } else {
+ OldSpace* target_space = Heap::TargetSpace(object);
+
+ ASSERT(target_space == Heap::old_pointer_space() ||
+ target_space == Heap::old_data_space());
+ result = target_space->AllocateRaw(object_size);
+ if (!result->IsFailure()) {
+ HeapObject* target = HeapObject::cast(result);
+ MigrateObject(target->address(), object->address(), object_size);
+ if (target_space == Heap::old_pointer_space()) {
+ Heap::UpdateRSet(target);
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+static void SweepNewSpace(NewSpace* space) {
+ Heap::CheckNewSpaceExpansionCriteria();
+
+ Address from_bottom = space->bottom();
+ Address from_top = space->top();
+
+ // Flip the semispaces. After flipping, to space is empty, from space has
+ // live objects.
+ space->Flip();
+ space->ResetAllocationInfo();
+
+ int size = 0;
+ int survivors_size = 0;
+
+ // First pass: traverse all objects in inactive semispace, remove marks,
+ // migrate live objects and write forwarding addresses.
+ for (Address current = from_bottom; current < from_top; current += size) {
+ HeapObject* object = HeapObject::FromAddress(current);
+
+ if (object->IsMarked()) {
+ object->ClearMark();
+ MarkCompactCollector::tracer()->decrement_marked_count();
+
+ size = object->Size();
+ survivors_size += size;
+
+ if (Heap::ShouldBePromoted(current, size) &&
+ TryPromoteObject(object, size)) {
+ continue;
+ }
+
+ // Promotion either failed or not required.
+ // Copy the content of the object.
+ Object* target = space->AllocateRaw(size);
+
+ // Allocation cannot fail at this point: semispaces are of equal size.
+ ASSERT(!target->IsFailure());
+
+ MigrateObject(HeapObject::cast(target)->address(), current, size);
+ } else {
+ size = object->Size();
+ Memory::Address_at(current) = NULL;
+ }
+ }
+
+ // Second pass: find pointers to new space and update them.
+ PointersToNewGenUpdatingVisitor updating_visitor;
+
+ // Update pointers in to space.
HeapObject* object;
for (Address current = space->bottom();
current < space->top();
current += object->Size()) {
object = HeapObject::FromAddress(current);
- if (object->IsMarked()) {
- object->ClearMark();
- MarkCompactCollector::tracer()->decrement_marked_count();
- } else {
- // We give non-live objects a map that will correctly give their size,
- // since their existing map might not be live after the collection.
- int size = object->Size();
- if (size >= ByteArray::kHeaderSize) {
- object->set_map(Heap::raw_unchecked_byte_array_map());
- ByteArray::cast(object)->set_length(ByteArray::LengthFor(size));
- } else {
- ASSERT(size == kPointerSize);
- object->set_map(Heap::raw_unchecked_one_pointer_filler_map());
- }
- ASSERT(object->Size() == size);
- }
- // The object is now unmarked for the call to Size() at the top of the
- // loop.
+
+ object->IterateBody(object->map()->instance_type(),
+ object->Size(),
+ &updating_visitor);
}
+
+ // Update roots.
+ Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE);
+
+ // Update pointers in old spaces.
+ Heap::IterateRSet(Heap::old_pointer_space(), &UpdatePointerToNewGen);
+ Heap::IterateRSet(Heap::map_space(), &UpdatePointerToNewGen);
+ Heap::lo_space()->IterateRSet(&UpdatePointerToNewGen);
+
+ // Update pointers from cells.
+ HeapObjectIterator cell_iterator(Heap::cell_space());
+ for (HeapObject* cell = cell_iterator.next();
+ cell != NULL;
+ cell = cell_iterator.next()) {
+ if (cell->IsJSGlobalPropertyCell()) {
+ Address value_address =
+ reinterpret_cast<Address>(cell) +
+ (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
+ updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
+ }
+ }
+
+ // Update pointers from external string table.
+ Heap::UpdateNewSpaceReferencesInExternalStringTable(
+ &UpdateNewSpaceReferenceInExternalStringTableEntry);
+
+ // All pointers were updated. Update auxiliary allocation info.
+ Heap::IncrementYoungSurvivorsCounter(survivors_size);
+ space->set_age_mark(space->top());
}
@@ -1382,10 +1561,12 @@
ASSERT(FreeListNode::IsFreeListNode(vacant_map));
ASSERT(map_to_evacuate->IsMap());
- memcpy(
- reinterpret_cast<void*>(vacant_map->address()),
- reinterpret_cast<void*>(map_to_evacuate->address()),
- Map::kSize);
+ ASSERT(Map::kSize % 4 == 0);
+
+ Heap::CopyBlock(reinterpret_cast<Object**>(vacant_map->address()),
+ reinterpret_cast<Object**>(map_to_evacuate->address()),
+ Map::kSize);
+
ASSERT(vacant_map->IsMap()); // Due to memcpy above.
MapWord forwarding_map_word = MapWord::FromMap(vacant_map);
@@ -1465,10 +1646,11 @@
SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock);
SweepSpace(Heap::code_space(), &DeallocateCodeBlock);
SweepSpace(Heap::cell_space(), &DeallocateCellBlock);
- SweepSpace(Heap::new_space());
+ SweepNewSpace(Heap::new_space());
SweepSpace(Heap::map_space(), &DeallocateMapBlock);
- int live_maps = Heap::map_space()->Size() / Map::kSize;
- ASSERT(live_map_objects_ == live_maps);
+ int live_maps_size = Heap::map_space()->Size();
+ int live_maps = live_maps_size / Map::kSize;
+ ASSERT(live_map_objects_size_ == live_maps_size);
if (Heap::map_space()->NeedsCompaction(live_maps)) {
MapCompact map_compact(live_maps);
@@ -1500,7 +1682,7 @@
Address start,
Address end,
HeapObjectCallback size_func) {
- int live_objects = 0;
+ int live_objects_size = 0;
Address current = start;
while (current < end) {
uint32_t encoded_map = Memory::uint32_at(current);
@@ -1509,11 +1691,12 @@
} else if (encoded_map == kMultiFreeEncoding) {
current += Memory::int_at(current + kIntSize);
} else {
- live_objects++;
- current += size_func(HeapObject::FromAddress(current));
+ int size = size_func(HeapObject::FromAddress(current));
+ current += size;
+ live_objects_size += size;
}
}
- return live_objects;
+ return live_objects_size;
}
@@ -1639,36 +1822,36 @@
Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
GlobalHandles::IterateWeakRoots(&updating_visitor);
- int live_maps = IterateLiveObjects(Heap::map_space(),
- &UpdatePointersInOldObject);
- int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
- &UpdatePointersInOldObject);
- int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
+ int live_maps_size = IterateLiveObjects(Heap::map_space(),
&UpdatePointersInOldObject);
- int live_codes = IterateLiveObjects(Heap::code_space(),
- &UpdatePointersInOldObject);
- int live_cells = IterateLiveObjects(Heap::cell_space(),
- &UpdatePointersInOldObject);
- int live_news = IterateLiveObjects(Heap::new_space(),
- &UpdatePointersInNewObject);
+ int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
+ &UpdatePointersInOldObject);
+ int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
+ &UpdatePointersInOldObject);
+ int live_codes_size = IterateLiveObjects(Heap::code_space(),
+ &UpdatePointersInOldObject);
+ int live_cells_size = IterateLiveObjects(Heap::cell_space(),
+ &UpdatePointersInOldObject);
+ int live_news_size = IterateLiveObjects(Heap::new_space(),
+ &UpdatePointersInNewObject);
// Large objects do not move, the map word can be updated directly.
LargeObjectIterator it(Heap::lo_space());
for (HeapObject* obj = it.next(); obj != NULL; obj = it.next())
UpdatePointersInNewObject(obj);
- USE(live_maps);
- USE(live_pointer_olds);
- USE(live_data_olds);
- USE(live_codes);
- USE(live_cells);
- USE(live_news);
- ASSERT(live_maps == live_map_objects_);
- ASSERT(live_data_olds == live_old_data_objects_);
- ASSERT(live_pointer_olds == live_old_pointer_objects_);
- ASSERT(live_codes == live_code_objects_);
- ASSERT(live_cells == live_cell_objects_);
- ASSERT(live_news == live_young_objects_);
+ USE(live_maps_size);
+ USE(live_pointer_olds_size);
+ USE(live_data_olds_size);
+ USE(live_codes_size);
+ USE(live_cells_size);
+ USE(live_news_size);
+ ASSERT(live_maps_size == live_map_objects_size_);
+ ASSERT(live_data_olds_size == live_old_data_objects_size_);
+ ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
+ ASSERT(live_codes_size == live_code_objects_size_);
+ ASSERT(live_cells_size == live_cell_objects_size_);
+ ASSERT(live_news_size == live_young_objects_size_);
}
@@ -1783,27 +1966,31 @@
#endif
// Relocates objects, always relocate map objects first. Relocating
// objects in other space relies on map objects to get object size.
- int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject);
- int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
- &RelocateOldPointerObject);
- int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
- &RelocateOldDataObject);
- int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);
- int live_cells = IterateLiveObjects(Heap::cell_space(), &RelocateCellObject);
- int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject);
+ int live_maps_size = IterateLiveObjects(Heap::map_space(),
+ &RelocateMapObject);
+ int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
+ &RelocateOldPointerObject);
+ int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
+ &RelocateOldDataObject);
+ int live_codes_size = IterateLiveObjects(Heap::code_space(),
+ &RelocateCodeObject);
+ int live_cells_size = IterateLiveObjects(Heap::cell_space(),
+ &RelocateCellObject);
+ int live_news_size = IterateLiveObjects(Heap::new_space(),
+ &RelocateNewObject);
- USE(live_maps);
- USE(live_data_olds);
- USE(live_pointer_olds);
- USE(live_codes);
- USE(live_cells);
- USE(live_news);
- ASSERT(live_maps == live_map_objects_);
- ASSERT(live_data_olds == live_old_data_objects_);
- ASSERT(live_pointer_olds == live_old_pointer_objects_);
- ASSERT(live_codes == live_code_objects_);
- ASSERT(live_cells == live_cell_objects_);
- ASSERT(live_news == live_young_objects_);
+ USE(live_maps_size);
+ USE(live_pointer_olds_size);
+ USE(live_data_olds_size);
+ USE(live_codes_size);
+ USE(live_cells_size);
+ USE(live_news_size);
+ ASSERT(live_maps_size == live_map_objects_size_);
+ ASSERT(live_data_olds_size == live_old_data_objects_size_);
+ ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
+ ASSERT(live_codes_size == live_code_objects_size_);
+ ASSERT(live_cells_size == live_cell_objects_size_);
+ ASSERT(live_news_size == live_young_objects_size_);
// Flip from and to spaces
Heap::new_space()->Flip();
@@ -1821,6 +2008,9 @@
PagedSpaces spaces;
for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next())
space->MCCommitRelocationInfo();
+
+ Heap::CheckNewSpaceExpansionCriteria();
+ Heap::IncrementYoungSurvivorsCounter(live_news_size);
}
@@ -1840,7 +2030,10 @@
Address old_addr = obj->address();
if (new_addr != old_addr) {
- memmove(new_addr, old_addr, Map::kSize); // copy contents
+ // Move contents.
+ Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
+ reinterpret_cast<Object**>(old_addr),
+ Map::kSize);
}
#ifdef DEBUG
@@ -1896,7 +2089,10 @@
Address old_addr = obj->address();
if (new_addr != old_addr) {
- memmove(new_addr, old_addr, obj_size); // Copy contents
+ // Move contents.
+ Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
+ reinterpret_cast<Object**>(old_addr),
+ obj_size);
}
ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());
@@ -1940,7 +2136,10 @@
Address old_addr = obj->address();
if (new_addr != old_addr) {
- memmove(new_addr, old_addr, obj_size); // Copy contents.
+ // Move contents.
+ Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
+ reinterpret_cast<Object**>(old_addr),
+ obj_size);
}
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
@@ -1976,9 +2175,9 @@
#endif
// New and old addresses cannot overlap.
- memcpy(reinterpret_cast<void*>(new_addr),
- reinterpret_cast<void*>(old_addr),
- obj_size);
+ Heap::CopyBlock(reinterpret_cast<Object**>(new_addr),
+ reinterpret_cast<Object**>(old_addr),
+ obj_size);
#ifdef DEBUG
if (FLAG_gc_verbose) {
diff --git a/src/mark-compact.h b/src/mark-compact.h
index ab572f6..27335f2 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -407,26 +407,26 @@
// Counters used for debugging the marking phase of mark-compact or
// mark-sweep collection.
- // Number of live objects in Heap::to_space_.
- static int live_young_objects_;
+ // Size of live objects in Heap::to_space_.
+ static int live_young_objects_size_;
- // Number of live objects in Heap::old_pointer_space_.
- static int live_old_pointer_objects_;
+ // Size of live objects in Heap::old_pointer_space_.
+ static int live_old_pointer_objects_size_;
- // Number of live objects in Heap::old_data_space_.
- static int live_old_data_objects_;
+ // Size of live objects in Heap::old_data_space_.
+ static int live_old_data_objects_size_;
- // Number of live objects in Heap::code_space_.
- static int live_code_objects_;
+ // Size of live objects in Heap::code_space_.
+ static int live_code_objects_size_;
- // Number of live objects in Heap::map_space_.
- static int live_map_objects_;
+ // Size of live objects in Heap::map_space_.
+ static int live_map_objects_size_;
- // Number of live objects in Heap::cell_space_.
- static int live_cell_objects_;
+ // Size of live objects in Heap::cell_space_.
+ static int live_cell_objects_size_;
- // Number of live objects in Heap::lo_space_.
- static int live_lo_objects_;
+ // Size of live objects in Heap::lo_space_.
+ static int live_lo_objects_size_;
// Number of live bytes in this collection.
static int live_bytes_;
diff --git a/src/objects.h b/src/objects.h
index 9197466..b07792c 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4632,6 +4632,26 @@
};
+// JSRegExpResult is just a JSArray with a specific initial map.
+// This initial map adds in-object properties for "index" and "input"
+// properties, as assigned by RegExp.prototype.exec, which allows
+// faster creation of RegExp exec results.
+// This class just holds constants used when creating the result.
+// After creation the result must be treated as a JSArray in all regards.
+class JSRegExpResult: public JSArray {
+ public:
+ // Offsets of object fields.
+ static const int kIndexOffset = JSArray::kSize;
+ static const int kInputOffset = kIndexOffset + kPointerSize;
+ static const int kSize = kInputOffset + kPointerSize;
+ // Indices of in-object properties.
+ static const int kIndexIndex = 0;
+ static const int kInputIndex = 1;
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
+};
+
+
// An accessor must have a getter, but can have no setter.
//
// When setting a property, V8 searches accessors in prototypes.
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 46e7aab..b809aab 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -327,7 +327,7 @@
CpuProfile* CpuProfilesCollection::StopProfiling(const char* title) {
- const int title_len = strlen(title);
+ const int title_len = StrLength(title);
CpuProfile* profile = NULL;
current_profiles_semaphore_->Wait();
for (int i = current_profiles_.length() - 1; i >= 0; --i) {
diff --git a/src/regexp.js b/src/regexp.js
index c76b09d..9929b11 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -135,19 +135,52 @@
var regExpCache = new RegExpCache();
-function CloneRegexpAnswer(array) {
+function CloneRegExpResult(array) {
if (array == null) return null;
- var len = array.length;
- var answer = new $Array(len);
- for (var i = 0; i < len; i++) {
+ var length = array.length;
+ var answer = %_RegExpConstructResult(length, array.index, array.input);
+ for (var i = 0; i < length; i++) {
answer[i] = array[i];
}
- answer.index = array.index;
- answer.input = array.input;
return answer;
}
+function BuildResultFromMatchInfo(lastMatchInfo, s) {
+ var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
+ var result = %_RegExpConstructResult(numResults, lastMatchInfo[CAPTURE0], s);
+ if (numResults === 1) {
+ var matchStart = lastMatchInfo[CAPTURE(0)];
+ var matchEnd = lastMatchInfo[CAPTURE(1)];
+ result[0] = SubString(s, matchStart, matchEnd);
+ } else {
+ for (var i = 0; i < numResults; i++) {
+ var matchStart = lastMatchInfo[CAPTURE(i << 1)];
+ var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)];
+ if (matchStart != -1 && matchEnd != -1) {
+ result[i] = SubString(s, matchStart, matchEnd);
+ } else {
+ // Make sure the element is present. Avoid reading the undefined
+ // property from the global object since this may change.
+ result[i] = void 0;
+ }
+ }
+ }
+ return result;
+}
+
+
+function RegExpExecNoTests(regexp, string, start) {
+ // Must be called with RegExp, string and positive integer as arguments.
+ var matchInfo = DoRegExpExec(regexp, string, start);
+ var result = null;
+ if (matchInfo !== null) {
+ result = BuildResultFromMatchInfo(matchInfo, string);
+ }
+ return result;
+}
+
+
function RegExpExec(string) {
if (!IS_REGEXP(this)) {
throw MakeTypeError('incompatible_method_receiver',
@@ -162,7 +195,7 @@
%_ObjectEquals(cache.regExp, this) &&
%_ObjectEquals(cache.subject, string)) {
if (cache.answerSaved) {
- return CloneRegexpAnswer(cache.answer);
+ return CloneRegExpResult(cache.answer);
} else {
saveAnswer = true;
}
@@ -205,36 +238,15 @@
return matchIndices; // No match.
}
- var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
- var result;
- if (numResults === 1) {
- var matchStart = lastMatchInfo[CAPTURE(0)];
- var matchEnd = lastMatchInfo[CAPTURE(1)];
- result = [SubString(s, matchStart, matchEnd)];
- } else {
- result = new $Array(numResults);
- for (var i = 0; i < numResults; i++) {
- var matchStart = lastMatchInfo[CAPTURE(i << 1)];
- var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)];
- if (matchStart != -1 && matchEnd != -1) {
- result[i] = SubString(s, matchStart, matchEnd);
- } else {
- // Make sure the element is present. Avoid reading the undefined
- // property from the global object since this may change.
- result[i] = void 0;
- }
- }
- }
+ var result = BuildResultFromMatchInfo(matchIndices, s);
- result.index = lastMatchInfo[CAPTURE0];
- result.input = s;
if (this.global) {
this.lastIndex = lastMatchInfo[CAPTURE1];
} else {
cache.regExp = this;
cache.subject = s;
cache.lastIndex = lastIndex;
- if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
+ if (saveAnswer) cache.answer = CloneRegExpResult(result);
cache.answerSaved = saveAnswer;
cache.type = 'exec';
}
diff --git a/src/runtime.cc b/src/runtime.cc
index dc0e9c8..3d112b0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1228,6 +1228,36 @@
}
+static Object* Runtime_RegExpConstructResult(Arguments args) {
+ ASSERT(args.length() == 3);
+ CONVERT_SMI_CHECKED(elements_count, args[0]);
+ if (elements_count > JSArray::kMaxFastElementsLength) {
+ return Top::ThrowIllegalOperation();
+ }
+ Object* new_object = Heap::AllocateFixedArrayWithHoles(elements_count);
+ if (new_object->IsFailure()) return new_object;
+ FixedArray* elements = FixedArray::cast(new_object);
+ new_object = Heap::AllocateRaw(JSRegExpResult::kSize,
+ NEW_SPACE,
+ OLD_POINTER_SPACE);
+ if (new_object->IsFailure()) return new_object;
+ {
+ AssertNoAllocation no_gc;
+ HandleScope scope;
+ reinterpret_cast<HeapObject*>(new_object)->
+ set_map(Top::global_context()->regexp_result_map());
+ }
+ JSArray* array = JSArray::cast(new_object);
+ array->set_properties(Heap::empty_fixed_array());
+ array->set_elements(elements);
+ array->set_length(Smi::FromInt(elements_count));
+ // Write in-object properties after the length of the array.
+ array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
+ array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
+ return array;
+}
+
+
static Object* Runtime_RegExpInitializeObject(Arguments args) {
AssertNoAllocation no_alloc;
ASSERT(args.length() == 5);
@@ -2512,7 +2542,7 @@
pattern_char,
string.length() - start_index));
if (pos == NULL) return -1;
- return pos - string.start();
+ return static_cast<int>(pos - string.start());
}
for (int i = start_index, n = string.length(); i < n; i++) {
if (pattern_char == string[i]) {
@@ -2570,7 +2600,7 @@
*complete = true;
return -1;
}
- i = pos - subject.start();
+ i = static_cast<int>(pos - subject.start());
} else {
if (subject[i] != pattern_first_char) continue;
}
@@ -2604,7 +2634,7 @@
pattern_first_char,
n - i + 1));
if (pos == NULL) return -1;
- i = pos - subject.start();
+ i = static_cast<int>(pos - subject.start());
} else {
if (subject[i] != pattern_first_char) continue;
}
@@ -6336,7 +6366,7 @@
static inline void DateYMDFromTimeAfter1970(int date,
int& year, int& month, int& day) {
#ifdef DEBUG
- int save_date = date; // Need this for ASSERT in the end.
+ int save_date = date; // Need this for ASSERT in the end.
#endif
year = 1970 + (4 * date + 2) / kDaysIn4Years;
@@ -6352,7 +6382,7 @@
static inline void DateYMDFromTimeSlow(int date,
int& year, int& month, int& day) {
#ifdef DEBUG
- int save_date = date; // Need this for ASSERT in the end.
+ int save_date = date; // Need this for ASSERT in the end.
#endif
date += kDaysOffset;
@@ -9749,7 +9779,8 @@
// Check if this break point is closer that what was previously found.
if (source_position <= statement_position &&
statement_position - source_position < distance) {
- closest_pc = it.rinfo()->pc() - code->instruction_start();
+ closest_pc =
+ static_cast<int>(it.rinfo()->pc() - code->instruction_start());
distance = statement_position - source_position;
// Check whether we can't get any closer.
if (distance == 0) break;
diff --git a/src/runtime.h b/src/runtime.h
index 870cfa6..69acd04 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -157,6 +157,7 @@
F(RegExpExec, 4, 1) \
F(RegExpExecMultiple, 4, 1) \
F(RegExpInitializeObject, 5, 1) \
+ F(RegExpConstructResult, 3, 1) \
\
/* Strings */ \
F(StringCharCodeAt, 2, 1) \
diff --git a/src/string.js b/src/string.js
index 300baf9..7ddc467 100644
--- a/src/string.js
+++ b/src/string.js
@@ -149,6 +149,16 @@
}
+function CloneDenseArray(array) {
+ if (array === null) return null;
+ var clone = new $Array(array.length);
+ for (var i = 0; i < array.length; i++) {
+ clone[i] = array[i];
+ }
+ return clone;
+}
+
+
// ECMA-262 section 15.5.4.9
//
// This function is implementation specific. For now, we do not
@@ -164,33 +174,37 @@
// ECMA-262 section 15.5.4.10
function StringMatch(regexp) {
- if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp);
var subject = TO_STRING_INLINE(this);
+ if (IS_REGEXP(regexp)) {
+ if (!regexp.global) return regexp.exec(subject);
+
+ var cache = regExpCache;
+ var saveAnswer = false;
- if (!regexp.global) return regexp.exec(subject);
-
- var cache = regExpCache;
- var saveAnswer = false;
-
- if (%_ObjectEquals(cache.type, 'match') &&
- %_ObjectEquals(cache.regExp, regexp) &&
- %_ObjectEquals(cache.subject, subject)) {
- if (cache.answerSaved) {
- return CloneRegexpAnswer(cache.answer);
- } else {
- saveAnswer = true;
+ if (%_ObjectEquals(cache.type, 'match') &&
+ %_ObjectEquals(cache.regExp, regexp) &&
+ %_ObjectEquals(cache.subject, subject)) {
+ if (cache.answerSaved) {
+ return CloneDenseArray(cache.answer);
+ } else {
+ saveAnswer = true;
+ }
}
+ %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
+ // lastMatchInfo is defined in regexp.js.
+ var result = %StringMatch(subject, regexp, lastMatchInfo);
+ cache.type = 'match';
+ cache.regExp = regexp;
+ cache.subject = subject;
+ if (saveAnswer) cache.answer = CloneDenseArray(result);
+ cache.answerSaved = saveAnswer;
+ return result;
}
-
- %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
- // lastMatchInfo is defined in regexp.js.
- var result = %StringMatch(subject, regexp, lastMatchInfo);
- cache.type = 'match';
- cache.regExp = regexp;
- cache.subject = subject;
- if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
- cache.answerSaved = saveAnswer;
- return result;
+ // Non-regexp argument.
+ regexp = new $RegExp(regexp);
+ // Don't check regexp exec cache, since the regexp is new.
+ // TODO(lrn): Change this if we start caching regexps here.
+ return RegExpExecNoTests(regexp, subject, 0);
}
@@ -599,7 +613,7 @@
%_ObjectEquals(cache.regExp, separator) &&
%_ObjectEquals(cache.subject, subject)) {
if (cache.answerSaved) {
- return CloneRegexpAnswer(cache.answer);
+ return CloneDenseArray(cache.answer);
} else {
saveAnswer = true;
}
@@ -665,10 +679,9 @@
startIndex = currentIndex = endIndex;
}
- if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
+ if (saveAnswer) cache.answer = CloneDenseArray(result);
cache.answerSaved = saveAnswer;
return result;
-
}
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 95877fb..d77dc25 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -93,6 +93,28 @@
}
+Object* StubCache::ComputeLoadNonexistent(String* name, JSObject* receiver) {
+ // The code stub for loading nonexistent properties can be reused
+ // for all names, so we use the empty_string as the name in the map
+ // code cache.
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
+ Object* code = receiver->map()->FindInCodeCache(Heap::empty_string(), flags);
+ if (code->IsUndefined()) {
+ LoadStubCompiler compiler;
+ code = compiler.CompileLoadNonexistent(receiver);
+ if (code->IsFailure()) return code;
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG,
+ Code::cast(code),
+ Heap::empty_string()));
+ Object* result = receiver->map()->UpdateCodeCache(Heap::empty_string(),
+ Code::cast(code));
+ if (result->IsFailure()) return result;
+ }
+ return Set(name, receiver->map(), Code::cast(code));
+}
+
+
Object* StubCache::ComputeLoadField(String* name,
JSObject* receiver,
JSObject* holder,
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 0ca37e7..8a68977 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -56,6 +56,8 @@
// Computes the right stub matching. Inserts the result in the
// cache before returning. This might compile a stub if needed.
+ static Object* ComputeLoadNonexistent(String* name, JSObject* receiver);
+
static Object* ComputeLoadField(String* name,
JSObject* receiver,
JSObject* holder,
@@ -461,18 +463,23 @@
class LoadStubCompiler: public StubCompiler {
public:
+ Object* CompileLoadNonexistent(JSObject* object);
+
Object* CompileLoadField(JSObject* object,
JSObject* holder,
int index,
String* name);
+
Object* CompileLoadCallback(String* name,
JSObject* object,
JSObject* holder,
AccessorInfo* callback);
+
Object* CompileLoadConstant(JSObject* object,
JSObject* holder,
Object* value,
String* name);
+
Object* CompileLoadInterceptor(JSObject* object,
JSObject* holder,
String* name);
@@ -494,17 +501,21 @@
JSObject* object,
JSObject* holder,
int index);
+
Object* CompileLoadCallback(String* name,
JSObject* object,
JSObject* holder,
AccessorInfo* callback);
+
Object* CompileLoadConstant(String* name,
JSObject* object,
JSObject* holder,
Object* value);
+
Object* CompileLoadInterceptor(JSObject* object,
JSObject* holder,
String* name);
+
Object* CompileLoadArrayLength(String* name);
Object* CompileLoadStringLength(String* name);
Object* CompileLoadFunctionPrototype(String* name);
diff --git a/src/utils.h b/src/utils.h
index b123057..fa24947 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -657,7 +657,7 @@
return dest;
}
-
} } // namespace v8::internal
+
#endif // V8_UTILS_H_
diff --git a/src/version.cc b/src/version.cc
index 7980ecc..a79dbd7 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 2
#define MINOR_VERSION 2
-#define BUILD_NUMBER 2
+#define BUILD_NUMBER 3
#define PATCH_LEVEL 0
#define CANDIDATE_VERSION false
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 0c5d481..6d332b7 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -1240,7 +1240,7 @@
// Set up the roots register.
ExternalReference roots_address = ExternalReference::roots_address();
- __ movq(r13, roots_address);
+ __ movq(kRootRegister, roots_address);
// Current stack contents:
// [rsp + 2 * kPointerSize ... ]: Internal frame
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 87ad4b0..1c26521 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -1494,6 +1494,26 @@
}
+void CodeGenerator::SetTypeForStackSlot(Slot* slot, TypeInfo info) {
+ ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER);
+ if (slot->type() == Slot::LOCAL) {
+ frame_->SetTypeForLocalAt(slot->index(), info);
+ } else {
+ frame_->SetTypeForParamAt(slot->index(), info);
+ }
+ if (FLAG_debug_code && info.IsSmi()) {
+ if (slot->type() == Slot::LOCAL) {
+ frame_->PushLocalAt(slot->index());
+ } else {
+ frame_->PushParameterAt(slot->index());
+ }
+ Result var = frame_->Pop();
+ var.ToRegister();
+ __ AbortIfNotSmi(var.reg(), "Non-smi value in smi-typed stack slot.");
+ }
+}
+
+
void CodeGenerator::VisitForStatement(ForStatement* node) {
ASSERT(!in_spilled_code());
Comment cmnt(masm_, "[ ForStatement");
@@ -1587,6 +1607,17 @@
}
CheckStack(); // TODO(1222600): ignore if body contains calls.
+
+ // We know that the loop index is a smi if it is not modified in the
+ // loop body and it is checked against a constant limit in the loop
+ // condition. In this case, we reset the static type information of the
+ // loop index to smi before compiling the body, the update expression, and
+ // the bottom check of the loop condition.
+ if (node->is_fast_smi_loop()) {
+ // Set number type of the loop variable to smi.
+ SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
+ }
+
Visit(node->body());
// If there is an update expression, compile it if necessary.
@@ -1606,6 +1637,13 @@
}
}
+ // Set the type of the loop variable to smi before compiling the test
+ // expression if we are in a fast smi loop condition.
+ if (node->is_fast_smi_loop() && has_valid_frame()) {
+ // Set number type of the loop variable to smi.
+ SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
+ }
+
// Based on the condition analysis, compile the backward jump as
// necessary.
switch (info) {
@@ -4130,6 +4168,97 @@
}
+void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
+ // No stub. This code only occurs a few times in regexp.js.
+ const int kMaxInlineLength = 100;
+ ASSERT_EQ(3, args->length());
+ Load(args->at(0)); // Size of array, smi.
+ Load(args->at(1)); // "index" property value.
+ Load(args->at(2)); // "input" property value.
+ {
+ VirtualFrame::SpilledScope spilled_scope;
+
+ Label slowcase;
+ Label done;
+ __ movq(r8, Operand(rsp, kPointerSize * 2));
+ __ JumpIfNotSmi(r8, &slowcase);
+ __ SmiToInteger32(rbx, r8);
+ __ cmpl(rbx, Immediate(kMaxInlineLength));
+ __ j(above, &slowcase);
+ // Smi-tagging is equivalent to multiplying by 2.
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+ // Allocate RegExpResult followed by FixedArray with size in ebx.
+ // JSArray: [Map][empty properties][Elements][Length-smi][index][input]
+ // Elements: [Map][Length][..elements..]
+ __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+ times_pointer_size,
+ rbx, // In: Number of elements.
+ rax, // Out: Start of allocation (tagged).
+ rcx, // Out: End of allocation.
+ rdx, // Scratch register
+ &slowcase,
+ TAG_OBJECT);
+ // rax: Start of allocated area, object-tagged.
+ // rbx: Number of array elements as int32.
+ // r8: Number of array elements as smi.
+
+ // Set JSArray map to global.regexp_result_map().
+ __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX));
+ __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
+ __ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX));
+ __ movq(FieldOperand(rax, HeapObject::kMapOffset), rdx);
+
+ // Set empty properties FixedArray.
+ __ Move(FieldOperand(rax, JSObject::kPropertiesOffset),
+ Factory::empty_fixed_array());
+
+ // Set elements to point to FixedArray allocated right after the JSArray.
+ __ lea(rcx, Operand(rax, JSRegExpResult::kSize));
+ __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
+
+ // Set input, index and length fields from arguments.
+ __ pop(FieldOperand(rax, JSRegExpResult::kInputOffset));
+ __ pop(FieldOperand(rax, JSRegExpResult::kIndexOffset));
+ __ lea(rsp, Operand(rsp, kPointerSize));
+ __ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);
+
+ // Fill out the elements FixedArray.
+ // rax: JSArray.
+ // rcx: FixedArray.
+ // rbx: Number of elements in array as int32.
+
+ // Set map.
+ __ Move(FieldOperand(rcx, HeapObject::kMapOffset),
+ Factory::fixed_array_map());
+ // Set length.
+ __ movq(FieldOperand(rcx, FixedArray::kLengthOffset), rbx);
+ // Fill contents of fixed-array with the-hole.
+ __ Move(rdx, Factory::the_hole_value());
+ __ lea(rcx, FieldOperand(rcx, FixedArray::kHeaderSize));
+ // Fill fixed array elements with hole.
+ // rax: JSArray.
+ // rbx: Number of elements in array that remains to be filled, as int32.
+ // rcx: Start of elements in FixedArray.
+ // rdx: the hole.
+ Label loop;
+ __ testl(rbx, rbx);
+ __ bind(&loop);
+ __ j(less_equal, &done); // Jump if ecx is negative or zero.
+ __ subl(rbx, Immediate(1));
+ __ movq(Operand(rcx, rbx, times_pointer_size, 0), rdx);
+ __ jmp(&loop);
+
+ __ bind(&slowcase);
+ __ CallRuntime(Runtime::kRegExpConstructResult, 3);
+
+ __ bind(&done);
+ }
+ frame_->Forget(3);
+ frame_->Push(rax);
+}
+
+
void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
@@ -5112,14 +5241,28 @@
ASSERT(cc == less || cc == equal || cc == greater_equal);
// If either side is a constant smi, optimize the comparison.
- bool left_side_constant_smi =
- left_side.is_constant() && left_side.handle()->IsSmi();
- bool right_side_constant_smi =
- right_side.is_constant() && right_side.handle()->IsSmi();
- bool left_side_constant_null =
- left_side.is_constant() && left_side.handle()->IsNull();
- bool right_side_constant_null =
- right_side.is_constant() && right_side.handle()->IsNull();
+ bool left_side_constant_smi = false;
+ bool left_side_constant_null = false;
+ bool left_side_constant_1_char_string = false;
+ if (left_side.is_constant()) {
+ left_side_constant_smi = left_side.handle()->IsSmi();
+ left_side_constant_null = left_side.handle()->IsNull();
+ left_side_constant_1_char_string =
+ (left_side.handle()->IsString() &&
+ String::cast(*left_side.handle())->length() == 1 &&
+ String::cast(*left_side.handle())->IsAsciiRepresentation());
+ }
+ bool right_side_constant_smi = false;
+ bool right_side_constant_null = false;
+ bool right_side_constant_1_char_string = false;
+ if (right_side.is_constant()) {
+ right_side_constant_smi = right_side.handle()->IsSmi();
+ right_side_constant_null = right_side.handle()->IsNull();
+ right_side_constant_1_char_string =
+ (right_side.handle()->IsString() &&
+ String::cast(*right_side.handle())->length() == 1 &&
+ String::cast(*right_side.handle())->IsAsciiRepresentation());
+ }
if (left_side_constant_smi || right_side_constant_smi) {
if (left_side_constant_smi && right_side_constant_smi) {
@@ -5259,6 +5402,141 @@
operand.Unuse();
dest->Split(not_zero);
}
+ } else if (left_side_constant_1_char_string ||
+ right_side_constant_1_char_string) {
+ if (left_side_constant_1_char_string && right_side_constant_1_char_string) {
+ // Trivial case, comparing two constants.
+ int left_value = String::cast(*left_side.handle())->Get(0);
+ int right_value = String::cast(*right_side.handle())->Get(0);
+ switch (cc) {
+ case less:
+ dest->Goto(left_value < right_value);
+ break;
+ case equal:
+ dest->Goto(left_value == right_value);
+ break;
+ case greater_equal:
+ dest->Goto(left_value >= right_value);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ // Only one side is a constant 1 character string.
+ // If left side is a constant 1-character string, reverse the operands.
+ // Since one side is a constant string, conversion order does not matter.
+ if (left_side_constant_1_char_string) {
+ Result temp = left_side;
+ left_side = right_side;
+ right_side = temp;
+ cc = ReverseCondition(cc);
+ // This may reintroduce greater or less_equal as the value of cc.
+ // CompareStub and the inline code both support all values of cc.
+ }
+ // Implement comparison against a constant string, inlining the case
+ // where both sides are strings.
+ left_side.ToRegister();
+
+ // Here we split control flow to the stub call and inlined cases
+ // before finally splitting it to the control destination. We use
+ // a jump target and branching to duplicate the virtual frame at
+ // the first split. We manually handle the off-frame references
+ // by reconstituting them on the non-fall-through path.
+ JumpTarget is_not_string, is_string;
+ Register left_reg = left_side.reg();
+ Handle<Object> right_val = right_side.handle();
+ ASSERT(StringShape(String::cast(*right_val)).IsSymbol());
+ Condition is_smi = masm()->CheckSmi(left_reg);
+ is_not_string.Branch(is_smi, &left_side);
+ Result temp = allocator_->Allocate();
+ ASSERT(temp.is_valid());
+ __ movq(temp.reg(),
+ FieldOperand(left_reg, HeapObject::kMapOffset));
+ __ movzxbl(temp.reg(),
+ FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
+ // If we are testing for equality then make use of the symbol shortcut.
+ // Check if the left hand side has the same type as the right hand
+ // side (which is always a symbol).
+ if (cc == equal) {
+ Label not_a_symbol;
+ ASSERT(kSymbolTag != 0);
+ // Ensure that no non-strings have the symbol bit set.
+ ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
+ __ testb(temp.reg(), Immediate(kIsSymbolMask)); // Test the symbol bit.
+ __ j(zero, ¬_a_symbol);
+ // They are symbols, so do identity compare.
+ __ Cmp(left_reg, right_side.handle());
+ dest->true_target()->Branch(equal);
+ dest->false_target()->Branch(not_equal);
+ __ bind(¬_a_symbol);
+ }
+ // Call the compare stub if the left side is not a flat ascii string.
+ __ andb(temp.reg(),
+ Immediate(kIsNotStringMask |
+ kStringRepresentationMask |
+ kStringEncodingMask));
+ __ cmpb(temp.reg(),
+ Immediate(kStringTag | kSeqStringTag | kAsciiStringTag));
+ temp.Unuse();
+ is_string.Branch(equal, &left_side);
+
+ // Setup and call the compare stub.
+ is_not_string.Bind(&left_side);
+ CompareStub stub(cc, strict, kCantBothBeNaN);
+ Result result = frame_->CallStub(&stub, &left_side, &right_side);
+ result.ToRegister();
+ __ SmiCompare(result.reg(), Smi::FromInt(0));
+ result.Unuse();
+ dest->true_target()->Branch(cc);
+ dest->false_target()->Jump();
+
+ is_string.Bind(&left_side);
+ // left_side is a sequential ASCII string.
+ ASSERT(left_side.reg().is(left_reg));
+ right_side = Result(right_val);
+ Result temp2 = allocator_->Allocate();
+ ASSERT(temp2.is_valid());
+ // Test string equality and comparison.
+ if (cc == equal) {
+ Label comparison_done;
+ __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
+ Immediate(1));
+ __ j(not_equal, &comparison_done);
+ uint8_t char_value =
+ static_cast<uint8_t>(String::cast(*right_val)->Get(0));
+ __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
+ Immediate(char_value));
+ __ bind(&comparison_done);
+ } else {
+ __ movl(temp2.reg(),
+ FieldOperand(left_side.reg(), String::kLengthOffset));
+ __ subl(temp2.reg(), Immediate(1));
+ Label comparison;
+ // If the length is 0 then the subtraction gave -1 which compares less
+ // than any character.
+ __ j(negative, &comparison);
+ // Otherwise load the first character.
+ __ movzxbl(temp2.reg(),
+ FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize));
+ __ bind(&comparison);
+ // Compare the first character of the string with the
+ // constant 1-character string.
+ uint8_t char_value =
+ static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
+ __ cmpb(temp2.reg(), Immediate(char_value));
+ Label characters_were_different;
+ __ j(not_equal, &characters_were_different);
+ // If the first character is the same then the long string sorts after
+ // the short one.
+ __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
+ Immediate(1));
+ __ bind(&characters_were_different);
+ }
+ temp2.Unuse();
+ left_side.Unuse();
+ right_side.Unuse();
+ dest->Split(cc);
+ }
} else { // Neither side is a constant Smi or null.
// If either side is a non-smi constant, skip the smi check.
bool known_non_smi =
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 081a8a8..dff8dc2 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -582,6 +582,8 @@
// Support for direct calls from JavaScript to native RegExp code.
void GenerateRegExpExec(ZoneList<Expression*>* args);
+ void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
+
// Fast support for number to string.
void GenerateNumberToString(ZoneList<Expression*>* args);
@@ -611,6 +613,8 @@
void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
void CodeForSourcePosition(int pos);
+ void SetTypeForStackSlot(Slot* slot, TypeInfo info);
+
#ifdef DEBUG
// True if the registers are valid for entry to a block. There should
// be no frame-external references to (non-reserved) registers.
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2781a84..2c47cf8 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -46,17 +46,17 @@
void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
- movq(destination, Operand(r13, index << kPointerSizeLog2));
+ movq(destination, Operand(kRootRegister, index << kPointerSizeLog2));
}
void MacroAssembler::PushRoot(Heap::RootListIndex index) {
- push(Operand(r13, index << kPointerSizeLog2));
+ push(Operand(kRootRegister, index << kPointerSizeLog2));
}
void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
- cmpq(with, Operand(r13, index << kPointerSizeLog2));
+ cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2));
}
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index b5bb636..dabb764 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -37,6 +37,7 @@
// a spare register). The register isn't callee save, and not used by the
// function calling convention.
static const Register kScratchRegister = { 10 }; // r10.
+static const Register kRootRegister = { 13 }; // r13
// Convenience for platform-independent signatures.
typedef Operand MemOperand;
diff --git a/src/x64/register-allocator-x64-inl.h b/src/x64/register-allocator-x64-inl.h
index d630b33..c7c18b3 100644
--- a/src/x64/register-allocator-x64-inl.h
+++ b/src/x64/register-allocator-x64-inl.h
@@ -38,7 +38,7 @@
bool RegisterAllocator::IsReserved(Register reg) {
return reg.is(rsp) || reg.is(rbp) || reg.is(rsi) ||
- reg.is(kScratchRegister);
+ reg.is(kScratchRegister) || reg.is(kRootRegister);
}
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 03b21a5..cd9a86d 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -1144,6 +1144,36 @@
}
+Object* LoadStubCompiler::CompileLoadNonexistent(JSObject* object) {
+ // ----------- S t a t e -------------
+ // -- rcx : name
+ // -- rsp[0] : return address
+ // -- rsp[8] : receiver
+ // -----------------------------------
+ Label miss;
+
+ // Load receiver.
+ __ movq(rax, Operand(rsp, kPointerSize));
+
+ // Check the maps of the full prototype chain.
+ JSObject* last = object;
+ while (last->GetPrototype() != Heap::null_value()) {
+ last = JSObject::cast(last->GetPrototype());
+ }
+ CheckPrototypes(object, rax, last, rbx, rdx, Heap::empty_string(), &miss);
+
+ // Return undefined if maps of the full prototype chain is still the same.
+ __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
+ __ ret(0);
+
+ __ bind(&miss);
+ GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+ // Return the generated code.
+ return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
+
Object* LoadStubCompiler::CompileLoadField(JSObject* object,
JSObject* holder,
int index,
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 4e4cf28..81d981e 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -95,7 +95,7 @@
i::HandleScope scope;
const char* aaa_str = "aaa";
i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
- i::Vector<const char>(aaa_str, strlen(aaa_str)));
+ i::Vector<const char>(aaa_str, i::StrLength(aaa_str)));
processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
*aaa_name,
i::Heap::empty_string(),
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index bfadd20..41be8c0 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -821,19 +821,20 @@
Page* page = Page::FromAddress(current_top);
Address current_page = page->address();
Address next_page = current_page + Page::kPageSize;
- int bytes_to_page = next_page - current_top;
+ int bytes_to_page = static_cast<int>(next_page - current_top);
if (bytes_to_page <= FixedArray::kHeaderSize) {
// Alas, need to cross another page to be able to
// put desired value.
next_page += Page::kPageSize;
- bytes_to_page = next_page - current_top;
+ bytes_to_page = static_cast<int>(next_page - current_top);
}
CHECK(bytes_to_page > FixedArray::kHeaderSize);
int* is_normal_page_ptr = &Page::FromAddress(next_page)->is_normal_page;
Address is_normal_page_addr = reinterpret_cast<Address>(is_normal_page_ptr);
- int bytes_to_allocate = (is_normal_page_addr - current_top) + kPointerSize;
+ int bytes_to_allocate =
+ static_cast<int>(is_normal_page_addr - current_top) + kPointerSize;
int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) /
kPointerSize;
@@ -917,7 +918,7 @@
}
// Step 3: now allocate fixed array and JSObject to fill the whole new space.
- int to_fill = *limit_addr - *top_addr - object_size;
+ int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size);
int fixed_array_len = LenFromSize(to_fill);
CHECK(fixed_array_len < FixedArray::kMaxLength);
@@ -935,7 +936,7 @@
// Create a reference to object in new space in jsobject.
jsobject->FastPropertyAtPut(-1, array);
- CHECK_EQ(0L, (*limit_addr - *top_addr));
+ CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr));
// Step 4: clone jsobject, but force always allocate first to create a clone
// in old pointer space.
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index aadb7d0..0e30092 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -347,38 +347,6 @@
}
-TEST(StringConcatFlatten) {
- InitializeVM();
- v8::HandleScope handle_scope;
-
- const char* stringA = "0123456789";
- const char* stringB = "ABCDEFGHIJ";
-
- v8::Local<v8::String> a = v8::String::New(stringA);
- v8::Local<v8::String> b = v8::String::New(stringB);
-
- v8::Local<v8::String> cons = v8::String::Concat(a, b);
-
- i::Handle<i::String> str = v8::Utils::OpenHandle(*cons);
- CHECK(!str->IsFlat());
-
- cons->Flatten();
-
- CHECK(str->IsFlat());
-
- char buffer[21];
- cons->WriteUtf8(buffer);
-
- for (int i = 0; i < 10; i++) {
- CHECK_EQ(stringA[i], buffer[i]);
- }
-
- for (int i = 0; i < 10; i++) {
- CHECK_EQ(stringB[i], buffer[i + 10]);
- }
-}
-
-
TEST(ExternalShortStringAdd) {
ZoneScope zone(DELETE_ON_EXIT);
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index a1a5821..f1c2462 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -163,6 +163,12 @@
// Performance critical function which cannot afford type checks.
"_CallFunction": true,
+ // Tries to allocate based on argument, and (correctly) throws
+ // out-of-memory if the request is too large. In practice, the
+ // size will be the number of captures of a RegExp.
+ "RegExpConstructResult": true,
+ "_RegExpConstructResult": true,
+
// LiveEdit feature is under development currently and has fragile input.
"LiveEditFindSharedFunctionInfosForScript": true,
"LiveEditGatherCompileInfo": true,
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index bc795f3..9e4c069 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -128,7 +128,6 @@
89A88E250E71A6C20043BA31 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
89A88E260E71A6C90043BA31 /* top.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1900E719B8F00D62E90 /* top.cc */; };
89A88E270E71A6CB0043BA31 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
- 89A88E280E71A6CC0043BA31 /* usage-analyzer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */; };
89A88E290E71A6CE0043BA31 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
89A88E2A0E71A6D00043BA31 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
89A88E2B0E71A6D10043BA31 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
@@ -189,7 +188,6 @@
89F23C790E78D5B2006B2466 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
89F23C7A0E78D5B2006B2466 /* top.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1900E719B8F00D62E90 /* top.cc */; };
89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
- 89F23C7C0E78D5B2006B2466 /* usage-analyzer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */; };
89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
@@ -222,7 +220,27 @@
9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
- 9FBE03DE10BD409900F8BFBA /* fast-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */; };
+ 9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
+ 9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
+ 9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
+ 9FA38BB61175B2D200C4CD55 /* flow-graph.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA31175B2D200C4CD55 /* flow-graph.cc */; };
+ 9FA38BB71175B2D200C4CD55 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
+ 9FA38BB81175B2D200C4CD55 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
+ 9FA38BB91175B2D200C4CD55 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
+ 9FA38BBA1175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
+ 9FA38BBB1175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
+ 9FA38BBC1175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
+ 9FA38BBD1175B2D200C4CD55 /* flow-graph.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA31175B2D200C4CD55 /* flow-graph.cc */; };
+ 9FA38BBE1175B2D200C4CD55 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
+ 9FA38BBF1175B2D200C4CD55 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
+ 9FA38BC01175B2D200C4CD55 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
+ 9FA38BC51175B2E500C4CD55 /* full-codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */; };
+ 9FA38BC61175B2E500C4CD55 /* jump-target-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC31175B2E500C4CD55 /* jump-target-ia32.cc */; };
+ 9FA38BC71175B2E500C4CD55 /* virtual-frame-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC41175B2E500C4CD55 /* virtual-frame-ia32.cc */; };
+ 9FA38BCE1175B30400C4CD55 /* assembler-thumb2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC91175B30400C4CD55 /* assembler-thumb2.cc */; };
+ 9FA38BCF1175B30400C4CD55 /* full-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */; };
+ 9FA38BD01175B30400C4CD55 /* jump-target-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCC1175B30400C4CD55 /* jump-target-arm.cc */; };
+ 9FA38BD11175B30400C4CD55 /* virtual-frame-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCD1175B30400C4CD55 /* virtual-frame-arm.cc */; };
9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */; };
9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03E110BD40EA00F8BFBA /* fast-codegen-ia32.cc */; };
9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03E410BD412600F8BFBA /* fast-codegen-arm.cc */; };
@@ -496,8 +514,6 @@
897FF1920E719B8F00D62E90 /* unicode-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unicode-inl.h"; sourceTree = "<group>"; };
897FF1930E719B8F00D62E90 /* unicode.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unicode.cc; sourceTree = "<group>"; };
897FF1940E719B8F00D62E90 /* unicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unicode.h; sourceTree = "<group>"; };
- 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "usage-analyzer.cc"; sourceTree = "<group>"; };
- 897FF1960E719B8F00D62E90 /* usage-analyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "usage-analyzer.h"; sourceTree = "<group>"; };
897FF1970E719B8F00D62E90 /* utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utils.cc; sourceTree = "<group>"; };
897FF1980E719B8F00D62E90 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
897FF1990E719B8F00D62E90 /* v8-counters.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "v8-counters.cc"; sourceTree = "<group>"; };
@@ -575,6 +591,40 @@
9FA37332116DD9F000C4CD55 /* vm-state-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state-inl.h"; sourceTree = "<group>"; };
9FA37333116DD9F000C4CD55 /* vm-state.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "vm-state.cc"; sourceTree = "<group>"; };
9FA37334116DD9F000C4CD55 /* vm-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state.h"; sourceTree = "<group>"; };
+ 9FA38B9B1175B2D200C4CD55 /* cached-powers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cached-powers.h"; sourceTree = "<group>"; };
+ 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "data-flow.cc"; sourceTree = "<group>"; };
+ 9FA38B9D1175B2D200C4CD55 /* data-flow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "data-flow.h"; sourceTree = "<group>"; };
+ 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "diy-fp.cc"; sourceTree = "<group>"; };
+ 9FA38B9F1175B2D200C4CD55 /* diy-fp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "diy-fp.h"; sourceTree = "<group>"; };
+ 9FA38BA01175B2D200C4CD55 /* double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = double.h; sourceTree = "<group>"; };
+ 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fast-dtoa.cc"; sourceTree = "<group>"; };
+ 9FA38BA21175B2D200C4CD55 /* fast-dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fast-dtoa.h"; sourceTree = "<group>"; };
+ 9FA38BA31175B2D200C4CD55 /* flow-graph.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "flow-graph.cc"; sourceTree = "<group>"; };
+ 9FA38BA41175B2D200C4CD55 /* flow-graph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "flow-graph.h"; sourceTree = "<group>"; };
+ 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "full-codegen.cc"; sourceTree = "<group>"; };
+ 9FA38BA61175B2D200C4CD55 /* full-codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "full-codegen.h"; sourceTree = "<group>"; };
+ 9FA38BA71175B2D200C4CD55 /* jump-target-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "jump-target-inl.h"; sourceTree = "<group>"; };
+ 9FA38BA81175B2D200C4CD55 /* jump-target-light-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "jump-target-light-inl.h"; sourceTree = "<group>"; };
+ 9FA38BA91175B2D200C4CD55 /* liveedit.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = liveedit.cc; sourceTree = "<group>"; };
+ 9FA38BAA1175B2D200C4CD55 /* liveedit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = liveedit.h; sourceTree = "<group>"; };
+ 9FA38BAB1175B2D200C4CD55 /* powers-ten.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "powers-ten.h"; sourceTree = "<group>"; };
+ 9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "splay-tree-inl.h"; sourceTree = "<group>"; };
+ 9FA38BAD1175B2D200C4CD55 /* splay-tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "splay-tree.h"; sourceTree = "<group>"; };
+ 9FA38BAE1175B2D200C4CD55 /* type-info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "type-info.cc"; sourceTree = "<group>"; };
+ 9FA38BAF1175B2D200C4CD55 /* type-info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "type-info.h"; sourceTree = "<group>"; };
+ 9FA38BB01175B2D200C4CD55 /* virtual-frame-heavy-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "virtual-frame-heavy-inl.h"; sourceTree = "<group>"; };
+ 9FA38BB11175B2D200C4CD55 /* virtual-frame-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "virtual-frame-inl.h"; sourceTree = "<group>"; };
+ 9FA38BB21175B2D200C4CD55 /* virtual-frame-light-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "virtual-frame-light-inl.h"; sourceTree = "<group>"; };
+ 9FA38BC11175B2E500C4CD55 /* fast-codegen-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "fast-codegen-ia32.h"; path = "ia32/fast-codegen-ia32.h"; sourceTree = "<group>"; };
+ 9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-ia32.cc"; path = "ia32/full-codegen-ia32.cc"; sourceTree = "<group>"; };
+ 9FA38BC31175B2E500C4CD55 /* jump-target-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "jump-target-ia32.cc"; path = "ia32/jump-target-ia32.cc"; sourceTree = "<group>"; };
+ 9FA38BC41175B2E500C4CD55 /* virtual-frame-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "virtual-frame-ia32.cc"; path = "ia32/virtual-frame-ia32.cc"; sourceTree = "<group>"; };
+ 9FA38BC81175B30400C4CD55 /* assembler-thumb2-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-thumb2-inl.h"; path = "arm/assembler-thumb2-inl.h"; sourceTree = "<group>"; };
+ 9FA38BC91175B30400C4CD55 /* assembler-thumb2.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "assembler-thumb2.cc"; path = "arm/assembler-thumb2.cc"; sourceTree = "<group>"; };
+ 9FA38BCA1175B30400C4CD55 /* assembler-thumb2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-thumb2.h"; path = "arm/assembler-thumb2.h"; sourceTree = "<group>"; };
+ 9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-arm.cc"; path = "arm/full-codegen-arm.cc"; sourceTree = "<group>"; };
+ 9FA38BCC1175B30400C4CD55 /* jump-target-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "jump-target-arm.cc"; path = "arm/jump-target-arm.cc"; sourceTree = "<group>"; };
+ 9FA38BCD1175B30400C4CD55 /* virtual-frame-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "virtual-frame-arm.cc"; path = "arm/virtual-frame-arm.cc"; sourceTree = "<group>"; };
9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fast-codegen.cc"; sourceTree = "<group>"; };
9FBE03DD10BD409900F8BFBA /* fast-codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fast-codegen.h"; sourceTree = "<group>"; };
9FBE03E110BD40EA00F8BFBA /* fast-codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "fast-codegen-ia32.cc"; path = "ia32/fast-codegen-ia32.cc"; sourceTree = "<group>"; };
@@ -628,8 +678,8 @@
8915B8660E719336009C4E19 = {
isa = PBXGroup;
children = (
- 897FF0CF0E71996900D62E90 /* v8 */,
897FF1C00E719CB600D62E90 /* Products */,
+ 897FF0CF0E71996900D62E90 /* v8 */,
);
sourceTree = "<group>";
};
@@ -637,8 +687,8 @@
isa = PBXGroup;
children = (
897FF0D10E71999E00D62E90 /* include */,
- 897FF0D00E71999800D62E90 /* src */,
897FF1B30E719BCE00D62E90 /* samples */,
+ 897FF0D00E71999800D62E90 /* src */,
897FF1B40E719BE800D62E90 /* tools */,
);
name = v8;
@@ -649,9 +699,9 @@
isa = PBXGroup;
children = (
897FF0D70E719AB300D62E90 /* C++ */,
+ 89A9C1630E71C8E300BE6CCA /* generated */,
897FF0D80E719ABA00D62E90 /* js */,
897FF0DE0E719B3400D62E90 /* third_party */,
- 89A9C1630E71C8E300BE6CCA /* generated */,
);
path = src;
sourceTree = "<group>";
@@ -669,6 +719,7 @@
897FF0D70E719AB300D62E90 /* C++ */ = {
isa = PBXGroup;
children = (
+ 897FF1750E719B8F00D62E90 /* SConscript */,
897FF0F60E719B8F00D62E90 /* accessors.cc */,
897FF0F70E719B8F00D62E90 /* accessors.h */,
897FF0F80E719B8F00D62E90 /* allocation.cc */,
@@ -683,6 +734,9 @@
897FF1000E719B8F00D62E90 /* assembler-ia32-inl.h */,
897FF1010E719B8F00D62E90 /* assembler-ia32.cc */,
897FF1020E719B8F00D62E90 /* assembler-ia32.h */,
+ 9FA38BC81175B30400C4CD55 /* assembler-thumb2-inl.h */,
+ 9FA38BC91175B30400C4CD55 /* assembler-thumb2.cc */,
+ 9FA38BCA1175B30400C4CD55 /* assembler-thumb2.h */,
897FF1030E719B8F00D62E90 /* assembler.cc */,
897FF1040E719B8F00D62E90 /* assembler.h */,
897FF1050E719B8F00D62E90 /* ast.cc */,
@@ -694,6 +748,7 @@
897FF10B0E719B8F00D62E90 /* builtins.cc */,
897FF10C0E719B8F00D62E90 /* builtins.h */,
89A15C630EE4661A00B48DEB /* bytecodes-irregexp.h */,
+ 9FA38B9B1175B2D200C4CD55 /* cached-powers.h */,
897FF10D0E719B8F00D62E90 /* char-predicates-inl.h */,
897FF10E0E719B8F00D62E90 /* char-predicates.h */,
897FF10F0E719B8F00D62E90 /* checks.cc */,
@@ -728,36 +783,46 @@
897FF1220E719B8F00D62E90 /* counters.h */,
897FF1230E719B8F00D62E90 /* cpu-arm.cc */,
897FF1240E719B8F00D62E90 /* cpu-ia32.cc */,
- 897FF1250E719B8F00D62E90 /* cpu.h */,
9F2B37231152CEA0007CDAF4 /* cpu-profiler-inl.h */,
9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */,
9F2B37251152CEA0007CDAF4 /* cpu-profiler.h */,
+ 897FF1250E719B8F00D62E90 /* cpu.h */,
+ 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */,
+ 9FA38B9D1175B2D200C4CD55 /* data-flow.h */,
893A722A0F7B4A3200303DD2 /* dateparser-inl.h */,
897FF1260E719B8F00D62E90 /* dateparser.cc */,
897FF1270E719B8F00D62E90 /* dateparser.h */,
+ 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */,
+ 8956B6CE0F5D86570033B5A2 /* debug-agent.h */,
898BD20C0EF6CC850068B00A /* debug-arm.cc */,
898BD20D0EF6CC850068B00A /* debug-ia32.cc */,
897FF1280E719B8F00D62E90 /* debug.cc */,
897FF1290E719B8F00D62E90 /* debug.h */,
- 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */,
- 8956B6CE0F5D86570033B5A2 /* debug-agent.h */,
897FF12A0E719B8F00D62E90 /* disasm-arm.cc */,
897FF12B0E719B8F00D62E90 /* disasm-ia32.cc */,
897FF12C0E719B8F00D62E90 /* disasm.h */,
897FF12D0E719B8F00D62E90 /* disassembler.cc */,
897FF12E0E719B8F00D62E90 /* disassembler.h */,
+ 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */,
+ 9FA38B9F1175B2D200C4CD55 /* diy-fp.h */,
+ 9FA38BA01175B2D200C4CD55 /* double.h */,
897FF12F0E719B8F00D62E90 /* dtoa-config.c */,
897FF1300E719B8F00D62E90 /* execution.cc */,
897FF1310E719B8F00D62E90 /* execution.h */,
897FF1320E719B8F00D62E90 /* factory.cc */,
897FF1330E719B8F00D62E90 /* factory.h */,
- 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */,
- 9FBE03DD10BD409900F8BFBA /* fast-codegen.h */,
9FBE03E410BD412600F8BFBA /* fast-codegen-arm.cc */,
9FBE03E110BD40EA00F8BFBA /* fast-codegen-ia32.cc */,
+ 9FA38BC11175B2E500C4CD55 /* fast-codegen-ia32.h */,
+ 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */,
+ 9FBE03DD10BD409900F8BFBA /* fast-codegen.h */,
+ 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */,
+ 9FA38BA21175B2D200C4CD55 /* fast-dtoa.h */,
89471C7F0EB23EE400B6874B /* flag-definitions.h */,
897FF1350E719B8F00D62E90 /* flags.cc */,
897FF1360E719B8F00D62E90 /* flags.h */,
+ 9FA38BA31175B2D200C4CD55 /* flow-graph.cc */,
+ 9FA38BA41175B2D200C4CD55 /* flow-graph.h */,
8981F5FE1010500F00D1520E /* frame-element.cc */,
8981F5FF1010500F00D1520E /* frame-element.h */,
897FF1370E719B8F00D62E90 /* frames-arm.cc */,
@@ -767,6 +832,10 @@
897FF13B0E719B8F00D62E90 /* frames-inl.h */,
897FF13C0E719B8F00D62E90 /* frames.cc */,
897FF13D0E719B8F00D62E90 /* frames.h */,
+ 9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */,
+ 9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */,
+ 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */,
+ 9FA38BA61175B2D200C4CD55 /* full-codegen.h */,
9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */,
9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */,
897FF13E0E719B8F00D62E90 /* global-handles.cc */,
@@ -778,10 +847,10 @@
897FF1440E719B8F00D62E90 /* hashmap.cc */,
897FF1450E719B8F00D62E90 /* hashmap.h */,
897FF1460E719B8F00D62E90 /* heap-inl.h */,
- 897FF1470E719B8F00D62E90 /* heap.cc */,
- 897FF1480E719B8F00D62E90 /* heap.h */,
9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */,
9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */,
+ 897FF1470E719B8F00D62E90 /* heap.cc */,
+ 897FF1480E719B8F00D62E90 /* heap.h */,
897FF1490E719B8F00D62E90 /* ic-arm.cc */,
897FF14A0E719B8F00D62E90 /* ic-ia32.cc */,
897FF14B0E719B8F00D62E90 /* ic-inl.h */,
@@ -791,22 +860,28 @@
89A15C670EE4665300B48DEB /* interpreter-irregexp.h */,
897FF14E0E719B8F00D62E90 /* jsregexp.cc */,
897FF14F0E719B8F00D62E90 /* jsregexp.h */,
+ 9FA38BCC1175B30400C4CD55 /* jump-target-arm.cc */,
895FA720107FFB15006F39D4 /* jump-target-heavy-inl.h */,
895FA720107FFB15006F39D4 /* jump-target-heavy-inl.h */,
895FA720107FFB15006F39D4 /* jump-target-heavy-inl.h */,
- 58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
- 58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
58950D4F0F55514900F3E8BA /* jump-target-heavy.cc */,
58950D4F0F55514900F3E8BA /* jump-target-heavy.cc */,
+ 9FA38BC31175B2E500C4CD55 /* jump-target-ia32.cc */,
+ 9FA38BA71175B2D200C4CD55 /* jump-target-inl.h */,
+ 9FA38BA81175B2D200C4CD55 /* jump-target-light-inl.h */,
+ 58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
+ 58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
58950D500F55514900F3E8BA /* jump-target.cc */,
58950D510F55514900F3E8BA /* jump-target.h */,
897FF1500E719B8F00D62E90 /* list-inl.h */,
897FF1510E719B8F00D62E90 /* list.h */,
- 897FF1520E719B8F00D62E90 /* log.cc */,
- 897FF1530E719B8F00D62E90 /* log.h */,
+ 9FA38BA91175B2D200C4CD55 /* liveedit.cc */,
+ 9FA38BAA1175B2D200C4CD55 /* liveedit.h */,
22A76C900FF259E600FDC694 /* log-inl.h */,
9F4B7B870FCC877A00DC4117 /* log-utils.cc */,
9F4B7B880FCC877A00DC4117 /* log-utils.h */,
+ 897FF1520E719B8F00D62E90 /* log.cc */,
+ 897FF1530E719B8F00D62E90 /* log.h */,
897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */,
897FF1550E719B8F00D62E90 /* macro-assembler-arm.h */,
897FF1560E719B8F00D62E90 /* macro-assembler-ia32.cc */,
@@ -834,6 +909,7 @@
893A72230F7B0FF200303DD2 /* platform-posix.cc */,
897FF1690E719B8F00D62E90 /* platform-win32.cc */,
897FF16A0E719B8F00D62E90 /* platform.h */,
+ 9FA38BAB1175B2D200C4CD55 /* powers-ten.h */,
897FF16B0E719B8F00D62E90 /* prettyprinter.cc */,
897FF16C0E719B8F00D62E90 /* prettyprinter.h */,
9F73E3AE114E61A100F84A5A /* profile-generator-inl.h */,
@@ -869,7 +945,6 @@
897FF1720E719B8F00D62E90 /* runtime.h */,
897FF1730E719B8F00D62E90 /* scanner.cc */,
897FF1740E719B8F00D62E90 /* scanner.h */,
- 897FF1750E719B8F00D62E90 /* SConscript */,
897FF1760E719B8F00D62E90 /* scopeinfo.cc */,
897FF1770E719B8F00D62E90 /* scopeinfo.h */,
897FF1780E719B8F00D62E90 /* scopes.cc */,
@@ -888,6 +963,8 @@
897FF1850E719B8F00D62E90 /* spaces-inl.h */,
897FF1860E719B8F00D62E90 /* spaces.cc */,
897FF1870E719B8F00D62E90 /* spaces.h */,
+ 9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */,
+ 9FA38BAD1175B2D200C4CD55 /* splay-tree.h */,
897FF1880E719B8F00D62E90 /* string-stream.cc */,
897FF1890E719B8F00D62E90 /* string-stream.h */,
897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */,
@@ -898,11 +975,11 @@
897FF18F0E719B8F00D62E90 /* token.h */,
897FF1900E719B8F00D62E90 /* top.cc */,
897FF1910E719B8F00D62E90 /* top.h */,
+ 9FA38BAE1175B2D200C4CD55 /* type-info.cc */,
+ 9FA38BAF1175B2D200C4CD55 /* type-info.h */,
897FF1920E719B8F00D62E90 /* unicode-inl.h */,
897FF1930E719B8F00D62E90 /* unicode.cc */,
897FF1940E719B8F00D62E90 /* unicode.h */,
- 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */,
- 897FF1960E719B8F00D62E90 /* usage-analyzer.h */,
897FF1970E719B8F00D62E90 /* utils.cc */,
897FF1980E719B8F00D62E90 /* utils.h */,
897FF1990E719B8F00D62E90 /* v8-counters.cc */,
@@ -915,12 +992,17 @@
897FF1A00E719B8F00D62E90 /* variables.h */,
897FF32F0FAA0ED200136CF6 /* version.cc */,
897FF3300FAA0ED200136CF6 /* version.h */,
- 58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
- 58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
+ 9FA38BCD1175B30400C4CD55 /* virtual-frame-arm.cc */,
58950D570F55514900F3E8BA /* virtual-frame-arm.h */,
+ 9FA38BB01175B2D200C4CD55 /* virtual-frame-heavy-inl.h */,
58950D580F55514900F3E8BA /* virtual-frame-heavy.cc */,
58950D580F55514900F3E8BA /* virtual-frame-heavy.cc */,
+ 9FA38BC41175B2E500C4CD55 /* virtual-frame-ia32.cc */,
58950D590F55514900F3E8BA /* virtual-frame-ia32.h */,
+ 9FA38BB11175B2D200C4CD55 /* virtual-frame-inl.h */,
+ 9FA38BB21175B2D200C4CD55 /* virtual-frame-light-inl.h */,
+ 58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
+ 58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
58950D5A0F55514900F3E8BA /* virtual-frame.cc */,
58950D5B0F55514900F3E8BA /* virtual-frame.h */,
9FA37332116DD9F000C4CD55 /* vm-state-inl.h */,
@@ -973,10 +1055,10 @@
897FF1B30E719BCE00D62E90 /* samples */ = {
isa = PBXGroup;
children = (
- 89A15C910EE46A1700B48DEB /* d8-readline.cc */,
893988150F2A3686007D5254 /* d8-debug.cc */,
893A72320F7B4AD700303DD2 /* d8-debug.h */,
89FB0E360F8E531900B04B3C /* d8-posix.cc */,
+ 89A15C910EE46A1700B48DEB /* d8-readline.cc */,
89FB0E370F8E531900B04B3C /* d8-windows.cc */,
89A15C920EE46A1700B48DEB /* d8.cc */,
89A15C930EE46A1700B48DEB /* d8.h */,
@@ -999,11 +1081,11 @@
897FF1C00E719CB600D62E90 /* Products */ = {
isa = PBXGroup;
children = (
- 8970F2F00E719FB2006AE7B5 /* libv8.a */,
897F767A0E71B4CC007ACF34 /* v8_shell */,
- 89F23C870E78D5B2006B2466 /* libv8-arm.a */,
- 89F23C950E78D5B6006B2466 /* v8_shell-arm */,
8939880B0F2A35FA007D5254 /* v8_shell */,
+ 89F23C950E78D5B6006B2466 /* v8_shell-arm */,
+ 89F23C870E78D5B2006B2466 /* libv8-arm.a */,
+ 8970F2F00E719FB2006AE7B5 /* libv8.a */,
);
name = Products;
sourceTree = "<group>";
@@ -1154,7 +1236,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-delay.js\"\\\n\" mirror-delay.js\"\\\n\" date-delay.js\"\\\n\" json-delay.js\"\\\n\" regexp-delay.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n \"${LIBRARIES_CC}.new\" \\\n \"${LIBRARIES_EMPTY_CC}.new\" \\\n \"CORE\" \\\n ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes. This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
+ shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n \"${LIBRARIES_CC}.new\" \\\n \"${LIBRARIES_EMPTY_CC}.new\" \\\n \"CORE\" \\\n ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes. This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
};
89F23C3D0E78D5B2006B2466 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@@ -1167,7 +1249,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-delay.js\"\\\n\" mirror-delay.js\"\\\n\" date-delay.js\"\\\n\" json-delay.js\"\\\n\" regexp-delay.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n \"${LIBRARIES_CC}.new\" \\\n \"${LIBRARIES_EMPTY_CC}.new\" \\\n \"CORE\" \\\n ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes. This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
+ shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n \"${LIBRARIES_CC}.new\" \\\n \"${LIBRARIES_EMPTY_CC}.new\" \\\n \"CORE\" \\\n ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes. This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -1176,10 +1258,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 8939880D0F2A362A007D5254 /* d8.cc in Sources */,
893988160F2A3688007D5254 /* d8-debug.cc in Sources */,
893988330F2A3B8F007D5254 /* d8-js.cc in Sources */,
89FB0E3A0F8E533F00B04B3C /* d8-posix.cc in Sources */,
+ 8939880D0F2A362A007D5254 /* d8.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1197,6 +1279,7 @@
89A88DF40E71A6160043BA31 /* builtins-ia32.cc in Sources */,
89A88DF50E71A6170043BA31 /* builtins.cc in Sources */,
89A88DF60E71A61C0043BA31 /* checks.cc in Sources */,
+ 9F2B3712114FF62D007CDAF4 /* circular-queue.cc in Sources */,
893CCE640E71D83700357A03 /* code-stubs.cc in Sources */,
89A88DF70E71A6240043BA31 /* codegen-ia32.cc in Sources */,
89A88DF80E71A6260043BA31 /* codegen.cc in Sources */,
@@ -1206,31 +1289,44 @@
89A88DFB0E71A6440043BA31 /* conversions.cc in Sources */,
89A88DFC0E71A6460043BA31 /* counters.cc in Sources */,
89A88DFD0E71A6470043BA31 /* cpu-ia32.cc in Sources */,
+ 9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+ 9FA38BBA1175B2D200C4CD55 /* data-flow.cc in Sources */,
89A88DFE0E71A6480043BA31 /* dateparser.cc in Sources */,
8956B6CF0F5D86730033B5A2 /* debug-agent.cc in Sources */,
898BD20E0EF6CC930068B00A /* debug-ia32.cc in Sources */,
89A88DFF0E71A6530043BA31 /* debug.cc in Sources */,
89A88E000E71A6540043BA31 /* disasm-ia32.cc in Sources */,
89A88E010E71A6550043BA31 /* disassembler.cc in Sources */,
+ 9FA38BBB1175B2D200C4CD55 /* diy-fp.cc in Sources */,
89A88E020E71A65A0043BA31 /* dtoa-config.c in Sources */,
89A88E030E71A65B0043BA31 /* execution.cc in Sources */,
89A88E040E71A65D0043BA31 /* factory.cc in Sources */,
+ 9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */,
+ 9FA38BBC1175B2D200C4CD55 /* fast-dtoa.cc in Sources */,
89A88E050E71A65D0043BA31 /* flags.cc in Sources */,
+ 9FA38BBD1175B2D200C4CD55 /* flow-graph.cc in Sources */,
+ 8981F6001010501900D1520E /* frame-element.cc in Sources */,
89A88E060E71A6600043BA31 /* frames-ia32.cc in Sources */,
89A88E070E71A6610043BA31 /* frames.cc in Sources */,
+ 9FA38BC51175B2E500C4CD55 /* full-codegen-ia32.cc in Sources */,
+ 9FA38BBE1175B2D200C4CD55 /* full-codegen.cc in Sources */,
9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */,
89A88E080E71A6620043BA31 /* global-handles.cc in Sources */,
89A88E090E71A6640043BA31 /* handles.cc in Sources */,
89A88E0A0E71A6650043BA31 /* hashmap.cc in Sources */,
+ 9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
89A88E0B0E71A66C0043BA31 /* heap.cc in Sources */,
89A88E0C0E71A66D0043BA31 /* ic-ia32.cc in Sources */,
89A88E0D0E71A66E0043BA31 /* ic.cc in Sources */,
89A15C850EE4678B00B48DEB /* interpreter-irregexp.cc in Sources */,
89A88E0E0E71A66F0043BA31 /* jsregexp.cc in Sources */,
+ 58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
+ 58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
+ 9FA38BC61175B2E500C4CD55 /* jump-target-ia32.cc in Sources */,
58950D5E0F55519800F3E8BA /* jump-target.cc in Sources */,
- 58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
- 58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
8900116C0E71CA2300F91F35 /* libraries.cc in Sources */,
+ 9FA38BBF1175B2D200C4CD55 /* liveedit.cc in Sources */,
+ 9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */,
89A88E0F0E71A6740043BA31 /* log.cc in Sources */,
89A88E100E71A6770043BA31 /* macro-assembler-ia32.cc in Sources */,
89A88E110E71A6780043BA31 /* mark-compact.cc in Sources */,
@@ -1239,9 +1335,10 @@
89A88E140E71A6870043BA31 /* objects.cc in Sources */,
9FC86ABD0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */,
89A88E150E71A68C0043BA31 /* parser.cc in Sources */,
- 893A72240F7B101400303DD2 /* platform-posix.cc in Sources */,
89A88E160E71A68E0043BA31 /* platform-macos.cc in Sources */,
+ 893A72240F7B101400303DD2 /* platform-posix.cc in Sources */,
89A88E170E71A6950043BA31 /* prettyprinter.cc in Sources */,
+ 9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */,
89A88E180E71A6960043BA31 /* property.cc in Sources */,
89A15C7B0EE466EB00B48DEB /* regexp-macro-assembler-ia32.cc in Sources */,
89A15C830EE4675E00B48DEB /* regexp-macro-assembler-irregexp.cc in Sources */,
@@ -1264,27 +1361,20 @@
89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */,
89A88E250E71A6C20043BA31 /* token.cc in Sources */,
89A88E260E71A6C90043BA31 /* top.cc in Sources */,
+ 9FA38BC01175B2D200C4CD55 /* type-info.cc in Sources */,
89A88E270E71A6CB0043BA31 /* unicode.cc in Sources */,
- 89A88E280E71A6CC0043BA31 /* usage-analyzer.cc in Sources */,
89A88E290E71A6CE0043BA31 /* utils.cc in Sources */,
89A88E2A0E71A6D00043BA31 /* v8-counters.cc in Sources */,
89A88E2B0E71A6D10043BA31 /* v8.cc in Sources */,
89A88E2C0E71A6D20043BA31 /* v8threads.cc in Sources */,
89A88E2D0E71A6D50043BA31 /* variables.cc in Sources */,
89B933AF0FAA0F9600201304 /* version.cc in Sources */,
- 58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
- 58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
58950D670F5551C400F3E8BA /* virtual-frame-heavy.cc in Sources */,
- 89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
- 9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */,
- 8981F6001010501900D1520E /* frame-element.cc in Sources */,
- 9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
- 9FBE03DE10BD409900F8BFBA /* fast-codegen.cc in Sources */,
- 9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */,
- 9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */,
- 9F2B3712114FF62D007CDAF4 /* circular-queue.cc in Sources */,
- 9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+ 9FA38BC71175B2E500C4CD55 /* virtual-frame-ia32.cc in Sources */,
+ 58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
+ 58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */,
+ 89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1304,12 +1394,14 @@
89F23C400E78D5B2006B2466 /* allocation.cc in Sources */,
89F23C410E78D5B2006B2466 /* api.cc in Sources */,
89F23C970E78D5E3006B2466 /* assembler-arm.cc in Sources */,
+ 9FA38BCE1175B30400C4CD55 /* assembler-thumb2.cc in Sources */,
89F23C430E78D5B2006B2466 /* assembler.cc in Sources */,
89F23C440E78D5B2006B2466 /* ast.cc in Sources */,
89F23C450E78D5B2006B2466 /* bootstrapper.cc in Sources */,
89F23C980E78D5E7006B2466 /* builtins-arm.cc in Sources */,
89F23C470E78D5B2006B2466 /* builtins.cc in Sources */,
89F23C480E78D5B2006B2466 /* checks.cc in Sources */,
+ 9F2B3711114FF62D007CDAF4 /* circular-queue.cc in Sources */,
89F23C490E78D5B2006B2466 /* code-stubs.cc in Sources */,
89F23C990E78D5E9006B2466 /* codegen-arm.cc in Sources */,
89F23C4B0E78D5B2006B2466 /* codegen.cc in Sources */,
@@ -1320,31 +1412,45 @@
89F23C4E0E78D5B2006B2466 /* conversions.cc in Sources */,
89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */,
89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */,
+ 9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+ 9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */,
89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */,
894599A30F5D8729008DA8FB /* debug-agent.cc in Sources */,
898BD20F0EF6CC9A0068B00A /* debug-arm.cc in Sources */,
89F23C520E78D5B2006B2466 /* debug.cc in Sources */,
89F23C9B0E78D5EE006B2466 /* disasm-arm.cc in Sources */,
89F23C540E78D5B2006B2466 /* disassembler.cc in Sources */,
+ 9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */,
89F23C550E78D5B2006B2466 /* dtoa-config.c in Sources */,
89F23C560E78D5B2006B2466 /* execution.cc in Sources */,
89F23C570E78D5B2006B2466 /* factory.cc in Sources */,
+ 9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */,
+ 9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */,
+ 9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */,
89F23C580E78D5B2006B2466 /* flags.cc in Sources */,
+ 9FA38BB61175B2D200C4CD55 /* flow-graph.cc in Sources */,
+ 8981F6011010502800D1520E /* frame-element.cc in Sources */,
89F23C9C0E78D5F1006B2466 /* frames-arm.cc in Sources */,
89F23C5A0E78D5B2006B2466 /* frames.cc in Sources */,
+ 9FA38BCF1175B30400C4CD55 /* full-codegen-arm.cc in Sources */,
+ 9FA38BB71175B2D200C4CD55 /* full-codegen.cc in Sources */,
9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */,
89F23C5B0E78D5B2006B2466 /* global-handles.cc in Sources */,
89F23C5C0E78D5B2006B2466 /* handles.cc in Sources */,
89F23C5D0E78D5B2006B2466 /* hashmap.cc in Sources */,
+ 9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
89F23C5E0E78D5B2006B2466 /* heap.cc in Sources */,
89F23C9D0E78D5FB006B2466 /* ic-arm.cc in Sources */,
89F23C600E78D5B2006B2466 /* ic.cc in Sources */,
890A13FE0EE9C47F00E49346 /* interpreter-irregexp.cc in Sources */,
89F23C610E78D5B2006B2466 /* jsregexp.cc in Sources */,
+ 9FA38BD01175B30400C4CD55 /* jump-target-arm.cc in Sources */,
+ 58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
+ 58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
58950D600F5551A300F3E8BA /* jump-target.cc in Sources */,
- 58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
- 58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
89F23C620E78D5B2006B2466 /* libraries.cc in Sources */,
+ 9FA38BB81175B2D200C4CD55 /* liveedit.cc in Sources */,
+ 9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */,
89F23C630E78D5B2006B2466 /* log.cc in Sources */,
89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */,
89F23C650E78D5B2006B2466 /* mark-compact.cc in Sources */,
@@ -1353,17 +1459,18 @@
89F23C680E78D5B2006B2466 /* objects.cc in Sources */,
9FC86ABE0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */,
89F23C690E78D5B2006B2466 /* parser.cc in Sources */,
- 893A72250F7B101B00303DD2 /* platform-posix.cc in Sources */,
89F23C6A0E78D5B2006B2466 /* platform-macos.cc in Sources */,
+ 893A72250F7B101B00303DD2 /* platform-posix.cc in Sources */,
89F23C6B0E78D5B2006B2466 /* prettyprinter.cc in Sources */,
+ 9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */,
89F23C6C0E78D5B2006B2466 /* property.cc in Sources */,
890A14010EE9C4B000E49346 /* regexp-macro-assembler-arm.cc in Sources */,
890A14020EE9C4B400E49346 /* regexp-macro-assembler-irregexp.cc in Sources */,
890A14030EE9C4B500E49346 /* regexp-macro-assembler-tracer.cc in Sources */,
890A14040EE9C4B700E49346 /* regexp-macro-assembler.cc in Sources */,
8944AD110F1D4D570028D560 /* regexp-stack.cc in Sources */,
- 58950D640F5551B500F3E8BA /* register-allocator.cc in Sources */,
58950D650F5551B600F3E8BA /* register-allocator-arm.cc in Sources */,
+ 58950D640F5551B500F3E8BA /* register-allocator.cc in Sources */,
89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */,
89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */,
89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */,
@@ -1379,27 +1486,20 @@
89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */,
89F23C790E78D5B2006B2466 /* token.cc in Sources */,
89F23C7A0E78D5B2006B2466 /* top.cc in Sources */,
+ 9FA38BB91175B2D200C4CD55 /* type-info.cc in Sources */,
89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */,
- 89F23C7C0E78D5B2006B2466 /* usage-analyzer.cc in Sources */,
89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */,
89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */,
89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */,
89F23C800E78D5B2006B2466 /* v8threads.cc in Sources */,
89F23C810E78D5B2006B2466 /* variables.cc in Sources */,
89B933B00FAA0F9D00201304 /* version.cc in Sources */,
- 58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
- 58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
+ 9FA38BD11175B30400C4CD55 /* virtual-frame-arm.cc in Sources */,
58950D690F5551CE00F3E8BA /* virtual-frame-light.cc in Sources */,
- 89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
- 9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */,
- 8981F6011010502800D1520E /* frame-element.cc in Sources */,
- 9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
- 9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */,
- 9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */,
- 9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */,
- 9F2B3711114FF62D007CDAF4 /* circular-queue.cc in Sources */,
- 9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+ 58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
+ 58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */,
+ 89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/tools/visual_studio/common.vsprops b/tools/visual_studio/common.vsprops
index e4f75a5..20bb119 100644
--- a/tools/visual_studio/common.vsprops
+++ b/tools/visual_studio/common.vsprops
@@ -8,7 +8,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="$(ProjectDir)\..\..\src;$(IntDir)\DerivedSources"
- PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;ENABLE_LOGGING_AND_PROFILING;ENABLE_DEBUGGER_SUPPORT"
+ PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;ENABLE_VMSTATE_TRACKING;ENABLE_LOGGING_AND_PROFILING;ENABLE_DEBUGGER_SUPPORT"
MinimalRebuild="false"
ExceptionHandling="0"
RuntimeTypeInfo="false"