Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(621)

Unified Diff: src/ia32/stub-cache-ia32.cc

Issue 669061: First take on custom call generators. (Closed)
Patch Set: Ultimate version Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/log.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/stub-cache-ia32.cc
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 697a71fd38f99b04f9d1b2f7605d60280e20ac37..2cda5201c5079aa121138bca3551b1d9786acecd 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -549,9 +549,8 @@ class CallOptimization BASE_EMBEDDED {
// fast api call builtin.
void AnalyzePossibleApiFunction(JSFunction* function) {
SharedFunctionInfo* sfi = function->shared();
- if (sfi->function_data()->IsUndefined()) return;
- FunctionTemplateInfo* info =
- FunctionTemplateInfo::cast(sfi->function_data());
+ if (!sfi->IsApiFunction()) return;
+ FunctionTemplateInfo* info = sfi->get_api_func_data();
// Require a C++ callback.
if (info->call_code()->IsUndefined()) return;
@@ -1210,6 +1209,107 @@ Object* CallStubCompiler::CompileCallField(JSObject* object,
}
+Object* CallStubCompiler::CompileArrayPushCall(Object* object,
+ JSObject* holder,
+ JSFunction* function,
+ String* name,
+ CheckType check) {
+ // ----------- S t a t e -------------
+ // -- ecx : name
+ // -- esp[0] : return address
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based)
+ // -- ...
+ // -- esp[(argc + 1) * 4] : receiver
+ // -----------------------------------
+ Label miss;
+
+ // Get the receiver from the stack.
+ const int argc = arguments().immediate();
+ __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
+
+ // Check that the receiver isn't a smi.
+ __ test(edx, Immediate(kSmiTagMask));
+ __ j(zero, &miss, not_taken);
+
+ CheckPrototypes(JSObject::cast(object), edx,
+ holder, ebx,
+ eax, name, &miss);
+
+ if (argc == 0) {
+ // Noop, return the length.
+ __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
+ __ ret((argc + 1) * kPointerSize);
+ } else {
+ // Get the elements array of the object.
+ __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
+
+ // Check that the elements are in fast mode (not dictionary).
+ __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
+ Immediate(Factory::fixed_array_map()));
+ __ j(not_equal, &miss, not_taken);
+
+ if (argc == 1) { // Otherwise fall through to call builtin.
+ Label call_builtin, exit, with_rset_update;
+
+ // Get the array's length into eax and calculate new length.
+ __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
+ __ add(Operand(eax), Immediate(argc << 1));
+
+ // Get the element's length into ecx.
+ __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
+ __ SmiTag(ecx);
+
+ // Check if we could survive without allocation, go to builtin otherwise.
+ __ cmp(eax, Operand(ecx));
+ __ j(greater, &call_builtin);
+
+ // Save new length.
+ __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
+
+ // Push the element.
+ __ lea(edx, FieldOperand(ebx,
+ eax, times_half_pointer_size,
+ FixedArray::kHeaderSize - argc * kPointerSize));
+ __ mov(ecx, Operand(esp, argc * kPointerSize));
+ __ mov(Operand(edx, 0), ecx);
+
+ // Check if wrote not a smi.
+ __ test(ecx, Immediate(kSmiTagMask));
+ __ j(not_zero, &with_rset_update);
+
+ __ bind(&exit);
+ __ ret((argc + 1) * kPointerSize);
+
+ __ bind(&with_rset_update);
+
+ __ InNewSpace(ebx, ecx, equal, &exit);
+
+ RecordWriteStub stub(ebx, edx, ecx);
+ __ CallStub(&stub);
+ __ ret((argc + 1) * kPointerSize);
+
+ __ bind(&call_builtin);
+ }
+
+ __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush),
+ argc + 1,
+ 1);
+ }
+
+ __ bind(&miss);
+
+ Handle<Code> ic = ComputeCallMiss(arguments().immediate());
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+
+ // Return the generated code.
+ String* function_name = NULL;
+ if (function->shared()->name()->IsString()) {
+ function_name = String::cast(function->shared()->name());
+ }
+ return GetCode(CONSTANT_FUNCTION, function_name);
+}
+
+
Object* CallStubCompiler::CompileCallConstant(Object* object,
JSObject* holder,
JSFunction* function,
@@ -1222,6 +1322,14 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
// -- ...
// -- esp[(argc + 1) * 4] : receiver
// -----------------------------------
+
+ SharedFunctionInfo* function_info = function->shared();
+ if (function_info->HasCustomCallGenerator()) {
+ CustomCallGenerator generator =
+ ToCData<CustomCallGenerator>(function_info->function_data());
+ return generator(this, object, holder, function, name, check);
+ }
+
Label miss_in_smi_check;
// Get the receiver from the stack.
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/log.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698