Update V8 to r5214 as required by WebKit r65072.
Change-Id: I387277a00cc0949597c0f69a8e4f2da60213c8f2
diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h
index eb2a04d..7fa151e 100644
--- a/src/ia32/assembler-ia32-inl.h
+++ b/src/ia32/assembler-ia32-inl.h
@@ -121,32 +121,33 @@
Address RelocInfo::call_address() {
- ASSERT(IsPatchedReturnSequence());
+ ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
+ (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
return Assembler::target_address_at(pc_ + 1);
}
void RelocInfo::set_call_address(Address target) {
- ASSERT(IsPatchedReturnSequence());
+ ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
+ (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
Assembler::set_target_address_at(pc_ + 1, target);
}
Object* RelocInfo::call_object() {
- ASSERT(IsPatchedReturnSequence());
return *call_object_address();
}
-Object** RelocInfo::call_object_address() {
- ASSERT(IsPatchedReturnSequence());
- return reinterpret_cast<Object**>(pc_ + 1);
+void RelocInfo::set_call_object(Object* target) {
+ *call_object_address() = target;
}
-void RelocInfo::set_call_object(Object* target) {
- ASSERT(IsPatchedReturnSequence());
- *call_object_address() = target;
+Object** RelocInfo::call_object_address() {
+ ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
+ (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
+ return reinterpret_cast<Object**>(pc_ + 1);
}
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index e011237..6c830cb 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -158,7 +158,8 @@
const int RelocInfo::kApplyMask =
RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
- 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE;
+ 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
+ 1 << RelocInfo::DEBUG_BREAK_SLOT;
bool RelocInfo::IsCodedSpecially() {
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 9a11075..ba7785b 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -138,7 +138,6 @@
owner_->set_state(previous_);
}
-
// -------------------------------------------------------------------------
// CodeGenerator implementation.
@@ -5309,6 +5308,30 @@
}
+class DeferredAllocateInNewSpace: public DeferredCode {
+ public:
+ DeferredAllocateInNewSpace(int size, Register target)
+ : size_(size), target_(target) {
+ ASSERT(size >= kPointerSize && size <= Heap::MaxObjectSizeInNewSpace());
+ set_comment("[ DeferredAllocateInNewSpace");
+ }
+ void Generate();
+
+ private:
+ int size_;
+ Register target_;
+};
+
+
+void DeferredAllocateInNewSpace::Generate() {
+ __ push(Immediate(Smi::FromInt(size_)));
+ __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
+ if (!target_.is(eax)) {
+ __ mov(target_, eax);
+ }
+}
+
+
void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
ASSERT(!in_safe_int32_mode());
Comment cmnt(masm_, "[ RegExp Literal");
@@ -5339,10 +5362,33 @@
__ cmp(boilerplate.reg(), Factory::undefined_value());
deferred->Branch(equal);
deferred->BindExit();
- literals.Unuse();
- // Push the boilerplate object.
+ // Register of boilerplate contains RegExp object.
+
+ Result tmp = allocator()->Allocate();
+ ASSERT(tmp.is_valid());
+
+ int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
+
+ DeferredAllocateInNewSpace* allocate_fallback =
+ new DeferredAllocateInNewSpace(size, literals.reg());
frame_->Push(&boilerplate);
+ frame_->SpillTop();
+ __ AllocateInNewSpace(size,
+ literals.reg(),
+ tmp.reg(),
+ no_reg,
+ allocate_fallback->entry_label(),
+ TAG_OBJECT);
+ allocate_fallback->BindExit();
+ boilerplate = frame_->Pop();
+ // Copy from boilerplate to clone and return clone.
+
+ for (int i = 0; i < size; i += kPointerSize) {
+ __ mov(tmp.reg(), FieldOperand(boilerplate.reg(), i));
+ __ mov(FieldOperand(literals.reg(), i), tmp.reg());
+ }
+ frame_->Push(&literals);
}
@@ -7525,6 +7571,39 @@
}
+void CodeGenerator::GenerateIsRegExpEquivalent(ZoneList<Expression*>* args) {
+ ASSERT_EQ(2, args->length());
+ Load(args->at(0));
+ Load(args->at(1));
+ Result right_res = frame_->Pop();
+ Result left_res = frame_->Pop();
+ right_res.ToRegister();
+ left_res.ToRegister();
+ Result tmp_res = allocator()->Allocate();
+ ASSERT(tmp_res.is_valid());
+ Register right = right_res.reg();
+ Register left = left_res.reg();
+ Register tmp = tmp_res.reg();
+ right_res.Unuse();
+ left_res.Unuse();
+ tmp_res.Unuse();
+ __ cmp(left, Operand(right));
+ destination()->true_target()->Branch(equal);
+ // Fail if either is a non-HeapObject.
+ __ mov(tmp, left);
+ __ and_(Operand(tmp), right);
+ __ test(Operand(tmp), Immediate(kSmiTagMask));
+ destination()->false_target()->Branch(equal);
+ __ CmpObjectType(left, JS_REGEXP_TYPE, tmp);
+ destination()->false_target()->Branch(not_equal);
+ __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset));
+ destination()->false_target()->Branch(not_equal);
+ __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
+ __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
+ destination()->Split(equal);
+}
+
+
void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
ASSERT(!in_safe_int32_mode());
if (CheckForInlineRuntimeCall(node)) {
@@ -12275,7 +12354,7 @@
void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
- Label get_result;
+ Label empty_handle;
Label prologue;
Label promote_scheduled_exception;
__ EnterApiExitFrame(ExitFrame::MODE_NORMAL, kStackSpace, kArgc);
@@ -12318,20 +12397,20 @@
// Dereference this to get to the location.
__ mov(eax, Operand(eax, 0));
}
- // Check if the result handle holds 0
+ // Check if the result handle holds 0.
__ test(eax, Operand(eax));
- __ j(not_zero, &get_result, taken);
- // It was zero; the result is undefined.
- __ mov(eax, Factory::undefined_value());
- __ jmp(&prologue);
+ __ j(zero, &empty_handle, not_taken);
// It was non-zero. Dereference to get the result value.
- __ bind(&get_result);
__ mov(eax, Operand(eax, 0));
__ bind(&prologue);
__ LeaveExitFrame(ExitFrame::MODE_NORMAL);
__ ret(0);
__ bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
+ __ bind(&empty_handle);
+ // It was zero; the result is undefined.
+ __ mov(eax, Factory::undefined_value());
+ __ jmp(&prologue);
}
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 66014a0..2368b23 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -635,7 +635,7 @@
// Instantiate the function based on the shared function info.
Result InstantiateFunction(Handle<SharedFunctionInfo> function_info);
- // Support for type checks.
+ // Support for types.
void GenerateIsSmi(ZoneList<Expression*>* args);
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args);
@@ -710,6 +710,9 @@
void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(ZoneList<Expression*>* args);
+ // Check whether two RegExps are equivalent
+ void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
+
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index 9b558bd..dfa6634 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -265,6 +265,10 @@
// -- context
// -- frame base
void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+ ExternalReference restarter_frame_function_slot =
+ ExternalReference(Debug_Address::RestarterFrameFunctionPointer());
+ __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
+
// We do not know our frame height, but set esp based on ebp.
__ lea(esp, Operand(ebp, -4 * kPointerSize));
@@ -288,8 +292,10 @@
#undef __
-void Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
- Handle<Code> code) {
+// TODO(LiveEdit): consider making it platform-independent.
+// TODO(LiveEdit): use more named constants instead of numbers.
+Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
+ Handle<Code> code) {
ASSERT(bottom_js_frame->is_java_script());
Address fp = bottom_js_frame->fp();
@@ -298,7 +304,10 @@
Memory::Object_at(fp - 3 * kPointerSize) = *code;
Memory::Object_at(fp - 2 * kPointerSize) = Smi::FromInt(StackFrame::INTERNAL);
+
+ return reinterpret_cast<Object**>(&Memory::Object_at(fp - 4 * kPointerSize));
}
+
const int Debug::kFrameDropperFrameSize = 5;
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index b2ff1fd..eb944e6 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -207,7 +207,7 @@
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
#endif
- CodeGenerator::RecordPositions(masm_, function()->end_position());
+ CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
__ RecordJSReturn();
// Do not use the leave instruction here because it is too short to
// patch with the code required by the debugger.
@@ -1196,27 +1196,54 @@
void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
Comment cmnt(masm_, "[ RegExpLiteral");
- Label done;
+ Label materialized;
// Registers will be used as follows:
// edi = JS function.
- // ebx = literals array.
- // eax = regexp literal.
+ // ecx = literals array.
+ // ebx = regexp literal.
+ // eax = regexp literal clone.
__ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
+ __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
int literal_offset =
FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
- __ mov(eax, FieldOperand(ebx, literal_offset));
- __ cmp(eax, Factory::undefined_value());
- __ j(not_equal, &done);
+ __ mov(ebx, FieldOperand(ecx, literal_offset));
+ __ cmp(ebx, Factory::undefined_value());
+ __ j(not_equal, &materialized);
+
// Create regexp literal using runtime function
// Result will be in eax.
- __ push(ebx);
+ __ push(ecx);
__ push(Immediate(Smi::FromInt(expr->literal_index())));
__ push(Immediate(expr->pattern()));
__ push(Immediate(expr->flags()));
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
- // Label done:
- __ bind(&done);
+ __ mov(ebx, eax);
+
+ __ bind(&materialized);
+ int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
+ Label allocated, runtime_allocate;
+ __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
+ __ jmp(&allocated);
+
+ __ bind(&runtime_allocate);
+ __ push(ebx);
+ __ push(Immediate(Smi::FromInt(size)));
+ __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
+ __ pop(ebx);
+
+ __ bind(&allocated);
+ // Copy the content into the newly allocated memory.
+ // (Unroll copy loop once for better throughput).
+ for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) {
+ __ mov(edx, FieldOperand(ebx, i));
+ __ mov(ecx, FieldOperand(ebx, i + kPointerSize));
+ __ mov(FieldOperand(eax, i), edx);
+ __ mov(FieldOperand(eax, i + kPointerSize), ecx);
+ }
+ if ((size % (2 * kPointerSize)) != 0) {
+ __ mov(edx, FieldOperand(ebx, size - kPointerSize));
+ __ mov(FieldOperand(eax, size - kPointerSize), edx);
+ }
Apply(context_, eax);
}
@@ -2650,6 +2677,43 @@
}
+void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
+ ASSERT_EQ(2, args->length());
+
+ Register right = eax;
+ Register left = ebx;
+ Register tmp = ecx;
+
+ VisitForValue(args->at(0), kStack);
+ VisitForValue(args->at(1), kAccumulator);
+ __ pop(left);
+
+ Label done, fail, ok;
+ __ cmp(left, Operand(right));
+ __ j(equal, &ok);
+ // Fail if either is a non-HeapObject.
+ __ mov(tmp, left);
+ __ and_(Operand(tmp), right);
+ __ test(Operand(tmp), Immediate(kSmiTagMask));
+ __ j(zero, &fail);
+ __ CmpObjectType(left, JS_REGEXP_TYPE, tmp);
+ __ j(not_equal, &fail);
+ __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset));
+ __ j(not_equal, &fail);
+ __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
+ __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
+ __ j(equal, &ok);
+ __ bind(&fail);
+ __ mov(eax, Immediate(Factory::false_value()));
+ __ jmp(&done);
+ __ bind(&ok);
+ __ mov(eax, Immediate(Factory::true_value()));
+ __ bind(&done);
+
+ Apply(context_, eax);
+}
+
+
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
Handle<String> name = expr->name();
if (name->length() > 0 && name->Get(0) == '_') {
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index cbf710c..2cd41a1 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -545,7 +545,7 @@
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label slow, check_string, index_smi, index_string;
+ Label slow, check_string, index_smi, index_string, property_array_property;
Label check_pixel_array, probe_dictionary, check_number_dictionary;
// Check that the key is a smi.
@@ -652,7 +652,7 @@
__ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys));
__ j(not_equal, &slow);
- // Get field offset and check that it is an in-object property.
+ // Get field offset.
// edx : receiver
// ebx : receiver's map
// eax : key
@@ -663,7 +663,7 @@
Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
__ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
__ sub(edi, Operand(ecx));
- __ j(above_equal, &slow);
+ __ j(above_equal, &property_array_property);
// Load in-object property.
__ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
@@ -672,6 +672,14 @@
__ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1);
__ ret(0);
+ // Load property array property.
+ __ bind(&property_array_property);
+ __ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset));
+ __ mov(eax, FieldOperand(eax, edi, times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1);
+ __ ret(0);
+
// Do a quick inline probe of the receiver's dictionary, if it
// exists.
__ bind(&probe_dictionary);
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index bb613ed..d0eeb77 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -672,20 +672,33 @@
// Load address of new object into result.
LoadAllocationTopHelper(result, result_end, scratch, flags);
+ Register top_reg = result_end.is_valid() ? result_end : result;
+
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
ExternalReference::new_space_allocation_limit_address();
- lea(result_end, Operand(result, object_size));
- cmp(result_end, Operand::StaticVariable(new_space_allocation_limit));
+
+ if (top_reg.is(result)) {
+ add(Operand(top_reg), Immediate(object_size));
+ } else {
+ lea(top_reg, Operand(result, object_size));
+ }
+ cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit));
j(above, gc_required, not_taken);
- // Tag result if requested.
- if ((flags & TAG_OBJECT) != 0) {
- lea(result, Operand(result, kHeapObjectTag));
- }
-
// Update allocation top.
- UpdateAllocationTopHelper(result_end, scratch);
+ UpdateAllocationTopHelper(top_reg, scratch);
+
+ // Tag result if requested.
+ if (top_reg.is(result)) {
+ if ((flags & TAG_OBJECT) != 0) {
+ sub(Operand(result), Immediate(object_size - kHeapObjectTag));
+ } else {
+ sub(Operand(result), Immediate(object_size));
+ }
+ } else if ((flags & TAG_OBJECT) != 0) {
+ add(Operand(result), Immediate(kHeapObjectTag));
+ }
}
@@ -1052,16 +1065,6 @@
}
-void MacroAssembler::CallExternalReference(ExternalReference ref,
- int num_arguments) {
- mov(eax, Immediate(num_arguments));
- mov(ebx, Immediate(ref));
-
- CEntryStub stub(1);
- CallStub(&stub);
-}
-
-
Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
int num_arguments) {
if (f->nargs >= 0 && f->nargs != num_arguments) {
@@ -1082,6 +1085,16 @@
}
+void MacroAssembler::CallExternalReference(ExternalReference ref,
+ int num_arguments) {
+ mov(eax, Immediate(num_arguments));
+ mov(ebx, Immediate(ref));
+
+ CEntryStub stub(1);
+ CallStub(&stub);
+}
+
+
void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
int num_arguments,
int result_size) {
@@ -1106,8 +1119,7 @@
ExternalReference extensions_address =
ExternalReference::handle_scope_extensions_address();
mov(scratch, Operand::StaticVariable(extensions_address));
- ASSERT_EQ(0, kSmiTag);
- shl(scratch, kSmiTagSize);
+ SmiTag(scratch);
push(scratch);
mov(Operand::StaticVariable(extensions_address), Immediate(0));
// Push next and limit pointers which will be wordsize aligned and
@@ -1131,16 +1143,14 @@
mov(scratch, Operand::StaticVariable(extensions_address));
cmp(Operand(scratch), Immediate(0));
j(equal, &write_back);
- // Calling a runtime function messes with registers so we save and
- // restore any one we're asked not to change
- if (saved.is_valid()) push(saved);
+ push(saved);
if (gc_allowed) {
CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
} else {
result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
if (result->IsFailure()) return result;
}
- if (saved.is_valid()) pop(saved);
+ pop(saved);
bind(&write_back);
ExternalReference limit_address =
@@ -1150,7 +1160,7 @@
ExternalReference::handle_scope_next_address();
pop(Operand::StaticVariable(next_address));
pop(scratch);
- shr(scratch, kSmiTagSize);
+ SmiUntag(scratch);
mov(Operand::StaticVariable(extensions_address), scratch);
return result;
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 02cfd4d..a17a2b4 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -393,12 +393,12 @@
// Convenience function: Same as above, but takes the fid instead.
void CallRuntime(Runtime::FunctionId id, int num_arguments);
- // Convenience function: call an external reference.
- void CallExternalReference(ExternalReference ref, int num_arguments);
-
// Convenience function: Same as above, but takes the fid instead.
Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
+ // Convenience function: call an external reference.
+ void CallExternalReference(ExternalReference ref, int num_arguments);
+
// Tail call of a runtime routine (jump).
// Like JumpToExternalReference, but also takes care of passing the number
// of parameters.
@@ -431,7 +431,7 @@
void PushHandleScope(Register scratch);
// Pops a handle scope using the specified scratch register and
- // ensuring that saved register, it is not no_reg, is left unchanged.
+ // ensuring that saved register is left unchanged.
void PopHandleScope(Register saved, Register scratch);
// As PopHandleScope, but does not perform a GC. Instead, returns a
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index e81fbc7..c21dd4f 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1033,24 +1033,23 @@
// Check that the maps haven't changed.
Register reg =
- CheckPrototypes(object, receiver, holder,
- scratch1, scratch2, scratch3, name, miss);
+ CheckPrototypes(object, receiver, holder, scratch1,
+ scratch2, scratch3, name, miss);
Handle<AccessorInfo> callback_handle(callback);
- Register other = reg.is(scratch1) ? scratch2 : scratch1;
__ EnterInternalFrame();
- __ PushHandleScope(other);
- // Push the stack address where the list of arguments ends
- __ mov(other, esp);
- __ sub(Operand(other), Immediate(2 * kPointerSize));
- __ push(other);
+ __ PushHandleScope(scratch2);
+ // Push the stack address where the list of arguments ends.
+ __ mov(scratch2, esp);
+ __ sub(Operand(scratch2), Immediate(2 * kPointerSize));
+ __ push(scratch2);
__ push(receiver); // receiver
__ push(reg); // holder
// Push data from AccessorInfo.
if (Heap::InNewSpace(callback_handle->data())) {
- __ mov(other, Immediate(callback_handle));
- __ push(FieldOperand(other, AccessorInfo::kDataOffset));
+ __ mov(scratch2, Immediate(callback_handle));
+ __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset));
} else {
__ push(Immediate(Handle<Object>(callback_handle->data())));
}
@@ -1077,7 +1076,7 @@
}
// We need to avoid using eax since that now holds the result.
- Register tmp = other.is(eax) ? reg : other;
+ Register tmp = scratch2.is(eax) ? reg : scratch2;
// Emitting PopHandleScope may try to allocate. Do not allow the
// assembler to perform a garbage collection but instead return a
// failure object.
@@ -1288,9 +1287,11 @@
}
-void CallStubCompiler::GenerateMissBranch() {
- Handle<Code> ic = ComputeCallMiss(arguments().immediate(), kind_);
- __ jmp(ic, RelocInfo::CODE_TARGET);
+Object* CallStubCompiler::GenerateMissBranch() {
+ Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_);
+ if (obj->IsFailure()) return obj;
+ __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
+ return obj;
}
@@ -1341,7 +1342,8 @@
// Handle call cache miss.
__ bind(&miss);
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(FIELD, name);
@@ -1488,7 +1490,8 @@
}
__ bind(&miss);
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(function);
@@ -1571,7 +1574,8 @@
1);
__ bind(&miss);
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(function);
@@ -1634,8 +1638,8 @@
__ ret((argc + 1) * kPointerSize);
__ bind(&miss);
-
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(function);
@@ -1701,9 +1705,8 @@
__ ret((argc + 1) * kPointerSize);
__ bind(&miss);
- // Restore function name in ecx.
-
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(function);
@@ -1857,7 +1860,8 @@
FreeSpaceForFastApiCall(masm(), eax);
}
__ bind(&miss_in_smi_check);
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(function);
@@ -1921,7 +1925,8 @@
// Handle load cache miss.
__ bind(&miss);
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(INTERCEPTOR, name);
@@ -2006,7 +2011,8 @@
// Handle call cache miss.
__ bind(&miss);
__ IncrementCounter(&Counters::call_global_inline_miss, 1);
- GenerateMissBranch();
+ Object* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
// Return the generated code.
return GetCode(NORMAL, name);