Version 3.7.11
Fixed bug when generating padding to ensure space for lazy deoptimization. (issue 1846)
Further reduced pause times due to GC.
Stability and performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@10089 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index c6c1009..68eebd3 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -72,9 +72,9 @@
// Get the function info from the stack.
__ mov(edx, Operand(esp, 1 * kPointerSize));
- int map_index = strict_mode_ == kStrictMode
- ? Context::STRICT_MODE_FUNCTION_MAP_INDEX
- : Context::FUNCTION_MAP_INDEX;
+ int map_index = (language_mode_ == CLASSIC_MODE)
+ ? Context::FUNCTION_MAP_INDEX
+ : Context::STRICT_MODE_FUNCTION_MAP_INDEX;
// Compute the function map in the current global context and set that
// as the map of the allocated object.
@@ -2485,6 +2485,8 @@
__ cmp(edx, Operand(ecx, kIntSize));
__ j(not_equal, &cache_miss, Label::kNear);
// Cache hit!
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->transcendental_cache_hit(), 1);
__ mov(eax, Operand(ecx, 2 * kIntSize));
if (tagged) {
__ fstp(0);
@@ -2495,6 +2497,7 @@
}
__ bind(&cache_miss);
+ __ IncrementCounter(counters->transcendental_cache_miss(), 1);
// Update cache with new value.
// We are short on registers, so use no_reg as scratch.
// This gives slightly larger code.
@@ -2566,6 +2569,7 @@
switch (type_) {
case TranscendentalCache::SIN: return Runtime::kMath_sin;
case TranscendentalCache::COS: return Runtime::kMath_cos;
+ case TranscendentalCache::TAN: return Runtime::kMath_tan;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
@@ -2579,7 +2583,9 @@
// Input value is on FP stack, and also in ebx/edx.
// Input value is possibly in xmm1.
// Address of result (a newly allocated HeapNumber) may be in eax.
- if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
+ if (type_ == TranscendentalCache::SIN ||
+ type_ == TranscendentalCache::COS ||
+ type_ == TranscendentalCache::TAN) {
// Both fsin and fcos require arguments in the range +/-2^63 and
// return NaN for infinities and NaN. They can share all code except
// the actual fsin/fcos operation.
@@ -2650,6 +2656,12 @@
case TranscendentalCache::COS:
__ fcos();
break;
+ case TranscendentalCache::TAN:
+ // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the
+ // FP register stack.
+ __ fptan();
+ __ fstp(0); // Pop FP register stack.
+ break;
default:
UNREACHABLE();
}
@@ -3599,26 +3611,40 @@
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
// First check for flat two byte string.
- __ and_(ebx,
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
+ __ and_(ebx, kIsNotStringMask |
+ kStringRepresentationMask |
+ kStringEncodingMask |
+ kShortExternalStringMask);
STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string, Label::kNear);
- // Any other flat string must be a flat ascii string.
- __ and_(ebx, Immediate(kIsNotStringMask | kStringRepresentationMask));
+ // Any other flat string must be a flat ascii string. None of the following
+ // string type tests will succeed if subject is not a string or a short
+ // external string.
+ __ and_(ebx, Immediate(kIsNotStringMask |
+ kStringRepresentationMask |
+ kShortExternalStringMask));
__ j(zero, &seq_ascii_string, Label::kNear);
+ // ebx: whether subject is a string and if yes, its string representation
// Check for flat cons string or sliced string.
// A flat cons string is a cons string where the second part is the empty
// string. In that case the subject string is just the first part of the cons
// string. Also in this case the first part of the cons string is known to be
// a sequential string or an external string.
// In the case of a sliced string its offset has to be taken into account.
- Label cons_string, check_encoding;
+ Label cons_string, external_string, check_encoding;
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
+ STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
+ STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
__ cmp(ebx, Immediate(kExternalStringTag));
__ j(less, &cons_string);
- __ j(equal, &runtime);
+ __ j(equal, &external_string);
+
+ // Catch non-string subject or short external string.
+ STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
+ __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag));
+ __ j(not_zero, &runtime);
// String is sliced.
__ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset));
@@ -3640,10 +3666,10 @@
kStringRepresentationMask | kStringEncodingMask);
STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string, Label::kNear);
- // Any other flat string must be ascii.
+ // Any other flat string must be sequential ascii or external.
__ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
kStringRepresentationMask);
- __ j(not_zero, &runtime);
+ __ j(not_zero, &external_string);
__ bind(&seq_ascii_string);
// eax: subject string (flat ascii)
@@ -3864,6 +3890,27 @@
__ mov(eax, Operand(esp, kLastMatchInfoOffset));
__ ret(4 * kPointerSize);
+ // External string. Short external strings have already been ruled out.
+ // eax: subject string (expected to be external)
+ // ebx: scratch
+ __ bind(&external_string);
+ __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+ if (FLAG_debug_code) {
+ // Assert that we do not have a cons or slice (indirect strings) here.
+ // Sequential strings have already been ruled out.
+ __ test_b(ebx, kIsIndirectStringMask);
+ __ Assert(zero, "external string expected, but not found");
+ }
+ __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
+ // Move the pointer so that offset-wise, it looks like a sequential string.
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
+ __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+ STATIC_ASSERT(kTwoByteStringTag == 0);
+ __ test_b(ebx, kStringEncodingMask);
+ __ j(not_zero, &seq_ascii_string);
+ __ jmp(&seq_two_byte_string);
+
// Do the runtime call to execute the regexp.
__ bind(&runtime);
__ TailCallRuntime(Runtime::kRegExpExec, 4, 1);