Update V8 to r5425 as required by WebKit r67178
Change-Id: Ic338e7242d33e5a024bd5978f4a5a3a681af4ebd
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 8106886..366b91e 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -868,7 +868,7 @@
FloatingPointHelper::LoadSSE2Operands(masm);
}
} else {
- FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime);
+ FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats);
}
switch (op_) {
@@ -889,7 +889,7 @@
__ AbortIfNotNumber(eax);
}
} else {
- FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx);
+ FloatingPointHelper::CheckFloatOperands(masm, ¬_floats, ebx);
}
FloatingPointHelper::LoadFloatOperands(
masm,
@@ -1004,7 +1004,13 @@
// If all else fails, use the runtime system to get the correct
// result. If arguments was passed in registers now place them on the
// stack in the correct order below the return address.
- __ bind(&call_runtime);
+
+ // Avoid hitting the string ADD code below when allocation fails in
+ // the floating point code above.
+ if (op_ != Token::ADD) {
+ __ bind(&call_runtime);
+ }
+
if (HasArgsInRegisters()) {
GenerateRegisterArgsPush(masm);
}
@@ -1012,7 +1018,6 @@
switch (op_) {
case Token::ADD: {
// Test for string arguments before calling runtime.
- Label not_strings, not_string1, string1, string1_smi2;
// If this stub has already generated FP-specific code then the arguments
// are already in edx, eax
@@ -1030,49 +1035,33 @@
rhs = eax;
}
- // Test if first argument is a string.
+ // Test if left operand is a string.
+ Label lhs_not_string;
__ test(lhs, Immediate(kSmiTagMask));
- __ j(zero, ¬_string1);
+ __ j(zero, &lhs_not_string);
__ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, ecx);
- __ j(above_equal, ¬_string1);
+ __ j(above_equal, &lhs_not_string);
- // First argument is a string, test second.
+ StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
+ __ TailCallStub(&string_add_left_stub);
+
+ Label call_runtime_with_args;
+ // Left operand is not a string, test right.
+ __ bind(&lhs_not_string);
__ test(rhs, Immediate(kSmiTagMask));
- __ j(zero, &string1_smi2);
+ __ j(zero, &call_runtime_with_args);
__ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx);
- __ j(above_equal, &string1);
+ __ j(above_equal, &call_runtime_with_args);
- // First and second argument are strings. Jump to the string add stub.
- StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
- __ TailCallStub(&string_add_stub);
+ StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
+ __ TailCallStub(&string_add_right_stub);
- __ bind(&string1_smi2);
- // First argument is a string, second is a smi. Try to lookup the number
- // string for the smi in the number string cache.
- NumberToStringStub::GenerateLookupNumberStringCache(
- masm, rhs, edi, ebx, ecx, true, &string1);
-
- // Replace second argument on stack and tailcall string add stub to make
- // the result.
- __ mov(Operand(esp, 1 * kPointerSize), edi);
- __ TailCallStub(&string_add_stub);
-
- // Only first argument is a string.
- __ bind(&string1);
- __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION);
-
- // First argument was not a string, test second.
- __ bind(¬_string1);
- __ test(rhs, Immediate(kSmiTagMask));
- __ j(zero, ¬_strings);
- __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx);
- __ j(above_equal, ¬_strings);
-
- // Only second argument is a string.
- __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION);
-
- __ bind(¬_strings);
// Neither argument is a string.
+ __ bind(&call_runtime);
+ if (HasArgsInRegisters()) {
+ GenerateRegisterArgsPush(masm);
+ }
+ __ bind(&call_runtime_with_args);
__ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
break;
}
@@ -3765,14 +3754,15 @@
void StringAddStub::Generate(MacroAssembler* masm) {
- Label string_add_runtime;
+ Label string_add_runtime, call_builtin;
+ Builtins::JavaScript builtin_id = Builtins::ADD;
// Load the two arguments.
__ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
__ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
// Make sure that both arguments are strings if not known in advance.
- if (string_check_) {
+ if (flags_ == NO_STRING_ADD_FLAGS) {
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &string_add_runtime);
__ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
@@ -3783,6 +3773,20 @@
__ j(zero, &string_add_runtime);
__ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
__ j(above_equal, &string_add_runtime);
+ } else {
+ // Here at least one of the arguments is definitely a string.
+ // We convert the one that is not known to be a string.
+ if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
+ ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
+ GenerateConvertArgument(masm, 2 * kPointerSize, eax, ebx, ecx, edi,
+ &call_builtin);
+ builtin_id = Builtins::STRING_ADD_RIGHT;
+ } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) {
+ ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0);
+ GenerateConvertArgument(masm, 1 * kPointerSize, edx, ebx, ecx, edi,
+ &call_builtin);
+ builtin_id = Builtins::STRING_ADD_LEFT;
+ }
}
// Both arguments are strings.
@@ -3828,21 +3832,41 @@
__ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
&string_add_runtime);
- // Get the two characters forming the sub string.
+ // Get the two characters forming the new string.
__ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
__ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
// Try to lookup two character string in symbol table. If it is not found
// just allocate a new one.
- Label make_two_character_string, make_flat_ascii_string;
+ Label make_two_character_string, make_two_character_string_no_reload;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
- masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
+ masm, ebx, ecx, eax, edx, edi,
+ &make_two_character_string_no_reload, &make_two_character_string);
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
+ // Allocate a two character string.
__ bind(&make_two_character_string);
- __ Set(ebx, Immediate(Smi::FromInt(2)));
- __ jmp(&make_flat_ascii_string);
+ // Reload the arguments.
+ __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
+ __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
+ // Get the two characters forming the new string.
+ __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
+ __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
+ __ bind(&make_two_character_string_no_reload);
+ __ IncrementCounter(&Counters::string_add_make_two_char, 1);
+ __ AllocateAsciiString(eax, // Result.
+ 2, // Length.
+ edi, // Scratch 1.
+ edx, // Scratch 2.
+ &string_add_runtime);
+ // Pack both characters in ebx.
+ __ shl(ecx, kBitsPerByte);
+ __ or_(ebx, Operand(ecx));
+ // Set the characters in the new string.
+ __ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx);
+ __ IncrementCounter(&Counters::string_add_native, 1);
+ __ ret(2 * kPointerSize);
__ bind(&longer_than_two);
// Check if resulting string will be flat.
@@ -3921,7 +3945,6 @@
__ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
__ j(zero, &string_add_runtime);
- __ bind(&make_flat_ascii_string);
// Both strings are ascii strings. As they are short they are both flat.
// ebx: length of resulting flat string as a smi
__ SmiUntag(ebx);
@@ -3997,6 +4020,56 @@
// Just jump to runtime to add the two strings.
__ bind(&string_add_runtime);
__ TailCallRuntime(Runtime::kStringAdd, 2, 1);
+
+ if (call_builtin.is_linked()) {
+ __ bind(&call_builtin);
+ __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
+ }
+}
+
+
+void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
+ int stack_offset,
+ Register arg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Label* slow) {
+ // First check if the argument is already a string.
+ Label not_string, done;
+ __ test(arg, Immediate(kSmiTagMask));
+ __ j(zero, ¬_string);
+ __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
+ __ j(below, &done);
+
+ // Check the number to string cache.
+ Label not_cached;
+ __ bind(¬_string);
+ // Puts the cached result into scratch1.
+ NumberToStringStub::GenerateLookupNumberStringCache(masm,
+ arg,
+ scratch1,
+ scratch2,
+ scratch3,
+ false,
+ ¬_cached);
+ __ mov(arg, scratch1);
+ __ mov(Operand(esp, stack_offset), arg);
+ __ jmp(&done);
+
+ // Check if the argument is a safe string wrapper.
+ __ bind(¬_cached);
+ __ test(arg, Immediate(kSmiTagMask));
+ __ j(zero, slow);
+ __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1.
+ __ j(not_equal, slow);
+ __ test_b(FieldOperand(scratch1, Map::kBitField2Offset),
+ 1 << Map::kStringWrapperSafeForDefaultValueOf);
+ __ j(zero, slow);
+ __ mov(arg, FieldOperand(arg, JSValue::kValueOffset));
+ __ mov(Operand(esp, stack_offset), arg);
+
+ __ bind(&done);
}
@@ -4092,6 +4165,7 @@
Register scratch1,
Register scratch2,
Register scratch3,
+ Label* not_probed,
Label* not_found) {
// Register scratch3 is the general scratch register in this function.
Register scratch = scratch3;
@@ -4106,7 +4180,7 @@
__ mov(scratch, c2);
__ sub(Operand(scratch), Immediate(static_cast<int>('0')));
__ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
- __ j(below_equal, not_found);
+ __ j(below_equal, not_probed);
__ bind(¬_array_index);
// Calculate the two character string hash.
@@ -4320,7 +4394,8 @@
// Try to lookup two character string in symbol table.
Label make_two_character_string;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
- masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
+ masm, ebx, ecx, eax, edx, edi,
+ &make_two_character_string, &make_two_character_string);
__ ret(3 * kPointerSize);
__ bind(&make_two_character_string);
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
index acf4a6f..351636f 100644
--- a/src/ia32/code-stubs-ia32.h
+++ b/src/ia32/code-stubs-ia32.h
@@ -234,16 +234,21 @@
Register scratch, // Neither of above.
bool ascii);
- // Probe the symbol table for a two character string. If the string is
- // not found by probing a jump to the label not_found is performed. This jump
- // does not guarantee that the string is not in the symbol table. If the
- // string is found the code falls through with the string in register eax.
+ // Probe the symbol table for a two character string. If the string
+ // requires non-standard hashing a jump to the label not_probed is
+ // performed and registers c1 and c2 are preserved. In all other
+ // cases they are clobbered. If the string is not found by probing a
+ // jump to the label not_found is performed. This jump does not
+ // guarantee that the string is not in the symbol table. If the
+ // string is found the code falls through with the string in
+ // register eax.
static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
Register c1,
Register c2,
Register scratch1,
Register scratch2,
Register scratch3,
+ Label* not_probed,
Label* not_found);
// Generate string hash.
@@ -267,24 +272,35 @@
// Flag that indicates how to generate code for the stub StringAddStub.
enum StringAddFlags {
NO_STRING_ADD_FLAGS = 0,
- NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub.
+ // Omit left string check in stub (left is definitely a string).
+ NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0,
+ // Omit right string check in stub (right is definitely a string).
+ NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1,
+ // Omit both string checks in stub.
+ NO_STRING_CHECK_IN_STUB =
+ NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB
};
class StringAddStub: public CodeStub {
public:
- explicit StringAddStub(StringAddFlags flags) {
- string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
- }
+ explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
private:
Major MajorKey() { return StringAdd; }
- int MinorKey() { return string_check_ ? 0 : 1; }
+ int MinorKey() { return flags_; }
void Generate(MacroAssembler* masm);
- // Should the stub check whether arguments are strings?
- bool string_check_;
+ void GenerateConvertArgument(MacroAssembler* masm,
+ int stack_offset,
+ Register arg,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Label* slow);
+
+ const StringAddFlags flags_;
};
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index d399c35..854052a 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -1411,12 +1411,12 @@
StringAddStub stub(NO_STRING_CHECK_IN_STUB);
answer = frame_->CallStub(&stub, 2);
} else {
- answer =
- frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2);
+ StringAddStub stub(NO_STRING_CHECK_LEFT_IN_STUB);
+ answer = frame_->CallStub(&stub, 2);
}
} else if (right_is_string) {
- answer =
- frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
+ StringAddStub stub(NO_STRING_CHECK_RIGHT_IN_STUB);
+ answer = frame_->CallStub(&stub, 2);
}
answer.set_type_info(TypeInfo::String());
frame_->Push(&answer);
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 2a8d313..adc0005 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -632,9 +632,6 @@
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
bool CheckForInlineRuntimeCall(CallRuntime* node);
- static bool PatchInlineRuntimeEntry(Handle<String> name,
- const InlineRuntimeLUT& new_entry,
- InlineRuntimeLUT* old_entry);
void ProcessDeclarations(ZoneList<Declaration*>* declarations);
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index c215142..87e25d7 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -782,6 +782,31 @@
}
+void MacroAssembler::AllocateAsciiString(Register result,
+ int length,
+ Register scratch1,
+ Register scratch2,
+ Label* gc_required) {
+ ASSERT(length > 0);
+
+ // Allocate ascii string in new space.
+ AllocateInNewSpace(SeqAsciiString::SizeFor(length),
+ result,
+ scratch1,
+ scratch2,
+ gc_required,
+ TAG_OBJECT);
+
+ // Set the map, length and hash field.
+ mov(FieldOperand(result, HeapObject::kMapOffset),
+ Immediate(Factory::ascii_string_map()));
+ mov(FieldOperand(result, String::kLengthOffset),
+ Immediate(Smi::FromInt(length)));
+ mov(FieldOperand(result, String::kHashFieldOffset),
+ Immediate(String::kEmptyHashField));
+}
+
+
void MacroAssembler::AllocateConsString(Register result,
Register scratch1,
Register scratch2,
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 5e850c0..a7534cb 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -356,6 +356,11 @@
Register scratch2,
Register scratch3,
Label* gc_required);
+ void AllocateAsciiString(Register result,
+ int length,
+ Register scratch1,
+ Register scratch2,
+ Label* gc_required);
// Allocate a raw cons string object. Only the map field of the result is
// initialized.