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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 155631: X64: Implement inline cache of monomorphic constant function call. Mark a de... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 18 matching lines...) Expand all
29 #include "v8.h" 29 #include "v8.h"
30 30
31 #include "ic-inl.h" 31 #include "ic-inl.h"
32 #include "codegen-inl.h" 32 #include "codegen-inl.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 #include "macro-assembler-x64.h" 34 #include "macro-assembler-x64.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 #define __ ACCESS_MASM((&masm_)) 39 #define __ ACCESS_MASM((masm()))
40 40
41 41
42 Object* CallStubCompiler::CompileCallConstant(Object* a, 42 Object* CallStubCompiler::CompileCallConstant(Object* object,
43 JSObject* b, 43 JSObject* holder,
44 JSFunction* c, 44 JSFunction* function,
45 String* d, 45 String* name,
46 StubCompiler::CheckType e) { 46 StubCompiler::CheckType check) {
47 // TODO(X64): Implement a real stub. 47 // ----------- S t a t e -------------
48 return Failure::InternalError(); 48 // -----------------------------------
49 // rsp[0] return address
50 // rsp[8] argument argc
51 // rsp[16] argument argc - 1
52 // ...
53 // rsp[argc * 8] argument 1
54 // rsp[(argc + 1) * 8] argument 0 = reciever
55 // rsp[(argc + 2) * 8] function name
56
57 Label miss;
58
59 // Get the receiver from the stack.
60 const int argc = arguments().immediate();
61 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
62
63 // Check that the receiver isn't a smi.
64 if (check != NUMBER_CHECK) {
65 __ testl(rdx, Immediate(kSmiTagMask));
66 __ j(zero, &miss);
67 }
68
69 // Make sure that it's okay not to patch the on stack receiver
70 // unless we're doing a receiver map check.
71 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
72
73 switch (check) {
74 case RECEIVER_MAP_CHECK:
75 // Check that the maps haven't changed.
76 CheckPrototypes(JSObject::cast(object), rdx, holder,
77 rbx, rcx, name, &miss);
78
79 // Patch the receiver on the stack with the global proxy if
80 // necessary.
81 if (object->IsGlobalObject()) {
82 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
83 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
84 }
85 break;
86
87 case STRING_CHECK:
88 // Check that the object is a two-byte string or a symbol.
89 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rcx);
90 __ j(above_equal, &miss);
91 // Check that the maps starting from the prototype haven't changed.
92 GenerateLoadGlobalFunctionPrototype(masm(),
93 Context::STRING_FUNCTION_INDEX,
94 rcx);
95 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder,
96 rbx, rdx, name, &miss);
97 break;
98
99 case NUMBER_CHECK: {
100 Label fast;
101 // Check that the object is a smi or a heap number.
102 __ testl(rdx, Immediate(kSmiTagMask));
103 __ j(zero, &fast);
104 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx);
105 __ j(not_equal, &miss);
106 __ bind(&fast);
107 // Check that the maps starting from the prototype haven't changed.
108 GenerateLoadGlobalFunctionPrototype(masm(),
109 Context::NUMBER_FUNCTION_INDEX,
110 rcx);
111 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder,
112 rbx, rdx, name, &miss);
113 break;
114 }
115
116 case BOOLEAN_CHECK: {
117 Label fast;
118 // Check that the object is a boolean.
119 __ Cmp(rdx, Factory::true_value());
120 __ j(equal, &fast);
121 __ Cmp(rdx, Factory::false_value());
122 __ j(not_equal, &miss);
123 __ bind(&fast);
124 // Check that the maps starting from the prototype haven't changed.
125 GenerateLoadGlobalFunctionPrototype(masm(),
126 Context::BOOLEAN_FUNCTION_INDEX,
127 rcx);
128 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder,
129 rbx, rdx, name, &miss);
130 break;
131 }
132
133 case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
134 CheckPrototypes(JSObject::cast(object), rdx, holder,
135 rbx, rcx, name, &miss);
136 // Make sure object->elements()->map() != Heap::dictionary_array_map()
137 // Get the elements array of the object.
138 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
139 // Check that the object is in fast mode (not dictionary).
140 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
141 Factory::hash_table_map());
142 __ j(equal, &miss);
143 break;
144
145 default:
146 UNREACHABLE();
147 }
148
149 // Get the function and setup the context.
150 __ Move(rdi, Handle<JSFunction>(function));
151 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
152
153 // Jump to the cached code (tail call).
154 ASSERT(function->is_compiled());
155 Handle<Code> code(function->code());
156 ParameterCount expected(function->shared()->formal_parameter_count());
157 __ InvokeCode(code, expected, arguments(),
158 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
159
160 // Handle call cache miss.
161 __ bind(&miss);
162 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
163 __ Jump(ic, RelocInfo::CODE_TARGET);
164
165 // Return the generated code.
166 String* function_name = NULL;
167 if (function->shared()->name()->IsString()) {
168 function_name = String::cast(function->shared()->name());
169 }
170 return GetCode(CONSTANT_FUNCTION, function_name);
49 } 171 }
50 172
173
51 Object* CallStubCompiler::CompileCallField(Object* a, 174 Object* CallStubCompiler::CompileCallField(Object* a,
52 JSObject* b, 175 JSObject* b,
53 int c, 176 int c,
54 String* d) { 177 String* d) {
55 // TODO(X64): Implement a real stub. 178 // TODO(X64): Implement a real stub.
56 return Failure::InternalError(); 179 return Failure::InternalError();
57 } 180 }
58 181
59 182
60 Object* CallStubCompiler::CompileCallInterceptor(Object* a, 183 Object* CallStubCompiler::CompileCallInterceptor(Object* a,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // Tear down temporary frame. 291 // Tear down temporary frame.
169 __ LeaveInternalFrame(); 292 __ LeaveInternalFrame();
170 293
171 // Do a tail-call of the compiled function. 294 // Do a tail-call of the compiled function.
172 __ lea(rcx, FieldOperand(rax, Code::kHeaderSize)); 295 __ lea(rcx, FieldOperand(rax, Code::kHeaderSize));
173 __ jmp(rcx); 296 __ jmp(rcx);
174 297
175 return GetCodeWithFlags(flags, "LazyCompileStub"); 298 return GetCodeWithFlags(flags, "LazyCompileStub");
176 } 299 }
177 300
301
302 Register StubCompiler::CheckPrototypes(JSObject* object,
303 Register object_reg,
304 JSObject* holder,
305 Register holder_reg,
306 Register scratch,
307 String* name,
308 Label* miss) {
309 // Check that the maps haven't changed.
310 Register result =
311 __ CheckMaps(object, object_reg, holder, holder_reg, scratch, miss);
312
313 // If we've skipped any global objects, it's not enough to verify
314 // that their maps haven't changed.
315 while (object != holder) {
316 if (object->IsGlobalObject()) {
317 GlobalObject* global = GlobalObject::cast(object);
318 Object* probe = global->EnsurePropertyCell(name);
319 if (probe->IsFailure()) {
320 set_failure(Failure::cast(probe));
321 return result;
322 }
323 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
324 ASSERT(cell->value()->IsTheHole());
325 __ Move(scratch, Handle<Object>(cell));
326 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
327 Factory::the_hole_value());
328 __ j(not_equal, miss);
329 }
330 object = JSObject::cast(object->GetPrototype());
331 }
332
333 // Return the register containing the holder.
334 return result;
335 }
336
337
338 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
339 int index,
340 Register prototype) {
341 // Load the global or builtins object from the current context.
Kasper Lund 2009/07/16 12:36:20 Why are we passing masm to this function? Isn't th
342 masm->movq(prototype,
343 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
344 // Load the global context from the global or builtins object.
345 masm->movq(prototype,
346 FieldOperand(prototype, GlobalObject::kGlobalContextOffset));
347 // Load the function from the global context.
348 masm->movq(prototype, Operand(prototype, Context::SlotOffset(index)));
349 // Load the initial map. The global functions all have initial maps.
350 masm->movq(prototype,
351 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
352 // Load the prototype from the initial map.
353 masm->movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
354 }
355
178 #undef __ 356 #undef __
179 357
180 358
181 } } // namespace v8::internal 359 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698