Version 3.17.16
Stack trace API: poison stack frames below the first strict mode frame. (issue 2564)
Made Isolate::GetHeapStatistics robust against half-initialized isolates (Chromium issue 2591).
Finished implementation of ES6 symbols aka. private names (issue 2158).
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@14137 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index b30d519..9b77c50 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -100,7 +100,7 @@
// stack param count needs (constructor pointer, and single argument)
descriptor->stack_parameter_count_ = &eax;
descriptor->register_params_ = registers;
- descriptor->extra_expression_stack_count_ = 1;
+ descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ArrayConstructor_StubFailure);
}
@@ -632,6 +632,14 @@
__ bind(¬_string);
}
+ if (types_.Contains(SYMBOL)) {
+ // Symbol value -> true.
+ Label not_symbol;
+ __ CmpInstanceType(map, SYMBOL_TYPE);
+ __ j(not_equal, ¬_symbol, Label::kNear);
+ __ bind(¬_symbol);
+ }
+
if (types_.Contains(HEAP_NUMBER)) {
// heap number -> false iff +0, -0, or NaN.
Label not_heap_number, false_result;
@@ -3296,25 +3304,6 @@
}
-void ArrayLengthStub::Generate(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
- Label miss;
-
- if (kind() == Code::KEYED_LOAD_IC) {
- __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string()));
- __ j(not_equal, &miss);
- }
-
- StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
- __ bind(&miss);
- StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
-}
-
-
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- ecx : name
@@ -3569,7 +3558,7 @@
__ add(ebx, Immediate(Heap::kArgumentsObjectSize));
// Do the allocation of all three objects in one go.
- __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
+ __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
// eax = address of new object(s) (tagged)
// ecx = argument count (tagged)
@@ -3767,7 +3756,7 @@
__ add(ecx, Immediate(Heap::kArgumentsObjectSizeStrict));
// Do the allocation of both objects in one go.
- __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
+ __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
// Get the arguments boilerplate from the current native context.
__ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
@@ -4291,15 +4280,15 @@
// 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,
- ebx, // In: Number of elements as a smi
- REGISTER_VALUE_IS_SMI,
- eax, // Out: Start of allocation (tagged).
- ecx, // Out: End of allocation.
- edx, // Scratch register
- &slowcase,
- TAG_OBJECT);
+ __ Allocate(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+ times_pointer_size,
+ ebx, // In: Number of elements as a smi
+ REGISTER_VALUE_IS_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().
@@ -4536,6 +4525,7 @@
// Identical objects can be compared fast, but there are some tricky cases
// for NaN and undefined.
+ Label generic_heap_number_comparison;
{
Label not_identical;
__ cmp(eax, edx);
@@ -4552,12 +4542,11 @@
__ bind(&check_for_nan);
}
- // Test for NaN. Sadly, we can't just compare to factory->nan_value(),
- // so we do the second best thing - test it ourselves.
- Label heap_number;
+ // Test for NaN. Compare heap numbers in a general way,
+ // to hanlde NaNs correctly.
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
Immediate(masm->isolate()->factory()->heap_number_map()));
- __ j(equal, &heap_number, Label::kNear);
+ __ j(equal, &generic_heap_number_comparison, Label::kNear);
if (cc != equal) {
// Call runtime on identical JSObjects. Otherwise return equal.
__ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
@@ -4566,37 +4555,6 @@
__ Set(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0);
- __ 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.
- STATIC_ASSERT(((kQuietNaNHighBitsMask << 1) & 0x80000000u) != 0);
- __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
- __ Set(eax, Immediate(0));
- // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
- // bits.
- __ add(edx, edx);
- __ cmp(edx, kQuietNaNHighBitsMask << 1);
- if (cc == equal) {
- STATIC_ASSERT(EQUAL != 1);
- __ setcc(above_equal, eax);
- __ ret(0);
- } else {
- Label nan;
- __ j(above_equal, &nan, Label::kNear);
- __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
- __ ret(0);
- __ bind(&nan);
- __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
- __ ret(0);
- }
__ bind(¬_identical);
}
@@ -4676,6 +4634,7 @@
// Generate the number comparison code.
Label non_number_comparison;
Label unordered;
+ __ bind(&generic_heap_number_comparison);
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatureScope use_sse2(masm, SSE2);
CpuFeatureScope use_cmov(masm, CMOV);
@@ -7836,8 +7795,10 @@
__ mov(ebx, MemOperand(ebp, parameter_count_offset));
masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
__ pop(ecx);
- __ lea(esp, MemOperand(esp, ebx, times_pointer_size,
- extra_expression_stack_count_ * kPointerSize));
+ int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE
+ ? kPointerSize
+ : 0;
+ __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset));
__ jmp(ecx); // Return to IC Miss stub, continuation still on stack.
}