OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 21 matching lines...) Expand all Loading... |
32 #include "ic-inl.h" | 32 #include "ic-inl.h" |
33 #include "codegen-inl.h" | 33 #include "codegen-inl.h" |
34 #include "stub-cache.h" | 34 #include "stub-cache.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 static void ProbeTable(MacroAssembler* masm, | 42 static void ProbeTable(Isolate* isolate, |
| 43 MacroAssembler* masm, |
43 Code::Flags flags, | 44 Code::Flags flags, |
44 StubCache::Table table, | 45 StubCache::Table table, |
45 Register name, | 46 Register name, |
46 Register offset) { | 47 Register offset) { |
47 ASSERT_EQ(8, kPointerSize); | 48 ASSERT_EQ(8, kPointerSize); |
48 ASSERT_EQ(16, sizeof(StubCache::Entry)); | 49 ASSERT_EQ(16, sizeof(StubCache::Entry)); |
49 // The offset register holds the entry offset times four (due to masking | 50 // The offset register holds the entry offset times four (due to masking |
50 // and shifting optimizations). | 51 // and shifting optimizations). |
51 ExternalReference key_offset(SCTableReference::keyReference(table)); | 52 ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); |
52 Label miss; | 53 Label miss; |
53 | 54 |
54 __ movq(kScratchRegister, key_offset); | 55 __ movq(kScratchRegister, key_offset); |
55 // Check that the key in the entry matches the name. | 56 // Check that the key in the entry matches the name. |
56 // Multiply entry offset by 16 to get the entry address. Since the | 57 // Multiply entry offset by 16 to get the entry address. Since the |
57 // offset register already holds the entry offset times four, multiply | 58 // offset register already holds the entry offset times four, multiply |
58 // by a further four. | 59 // by a further four. |
59 __ cmpl(name, Operand(kScratchRegister, offset, times_4, 0)); | 60 __ cmpl(name, Operand(kScratchRegister, offset, times_4, 0)); |
60 __ j(not_equal, &miss); | 61 __ j(not_equal, &miss); |
61 // Get the code entry from the cache. | 62 // Get the code entry from the cache. |
(...skipping 19 matching lines...) Expand all Loading... |
81 // must always call a backup property check that is complete. | 82 // must always call a backup property check that is complete. |
82 // This function is safe to call if the receiver has fast properties. | 83 // This function is safe to call if the receiver has fast properties. |
83 // Name must be a symbol and receiver must be a heap object. | 84 // Name must be a symbol and receiver must be a heap object. |
84 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 85 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
85 Label* miss_label, | 86 Label* miss_label, |
86 Register receiver, | 87 Register receiver, |
87 String* name, | 88 String* name, |
88 Register r0, | 89 Register r0, |
89 Register r1) { | 90 Register r1) { |
90 ASSERT(name->IsSymbol()); | 91 ASSERT(name->IsSymbol()); |
91 __ IncrementCounter(&Counters::negative_lookups, 1); | 92 __ IncrementCounter(COUNTERS->negative_lookups(), 1); |
92 __ IncrementCounter(&Counters::negative_lookups_miss, 1); | 93 __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1); |
93 | 94 |
94 Label done; | 95 Label done; |
95 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 96 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
96 | 97 |
97 const int kInterceptorOrAccessCheckNeededMask = | 98 const int kInterceptorOrAccessCheckNeededMask = |
98 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 99 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
99 | 100 |
100 // Bail out if the receiver has a named interceptor or requires access checks. | 101 // Bail out if the receiver has a named interceptor or requires access checks. |
101 __ testb(FieldOperand(r0, Map::kBitFieldOffset), | 102 __ testb(FieldOperand(r0, Map::kBitFieldOffset), |
102 Immediate(kInterceptorOrAccessCheckNeededMask)); | 103 Immediate(kInterceptorOrAccessCheckNeededMask)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 | 145 |
145 // Scale the index by multiplying by the entry size. | 146 // Scale the index by multiplying by the entry size. |
146 ASSERT(StringDictionary::kEntrySize == 3); | 147 ASSERT(StringDictionary::kEntrySize == 3); |
147 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. | 148 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. |
148 | 149 |
149 Register entity_name = r1; | 150 Register entity_name = r1; |
150 // Having undefined at this place means the name is not contained. | 151 // Having undefined at this place means the name is not contained. |
151 ASSERT_EQ(kSmiTagSize, 1); | 152 ASSERT_EQ(kSmiTagSize, 1); |
152 __ movq(entity_name, Operand(properties, index, times_pointer_size, | 153 __ movq(entity_name, Operand(properties, index, times_pointer_size, |
153 kElementsStartOffset - kHeapObjectTag)); | 154 kElementsStartOffset - kHeapObjectTag)); |
154 __ Cmp(entity_name, Factory::undefined_value()); | 155 __ Cmp(entity_name, FACTORY->undefined_value()); |
155 // __ jmp(miss_label); | 156 // __ jmp(miss_label); |
156 if (i != kProbes - 1) { | 157 if (i != kProbes - 1) { |
157 __ j(equal, &done); | 158 __ j(equal, &done); |
158 | 159 |
159 // Stop if found the property. | 160 // Stop if found the property. |
160 __ Cmp(entity_name, Handle<String>(name)); | 161 __ Cmp(entity_name, Handle<String>(name)); |
161 __ j(equal, miss_label); | 162 __ j(equal, miss_label); |
162 | 163 |
163 // Check if the entry name is not a symbol. | 164 // Check if the entry name is not a symbol. |
164 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); | 165 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); |
165 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | 166 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), |
166 Immediate(kIsSymbolMask)); | 167 Immediate(kIsSymbolMask)); |
167 __ j(zero, miss_label); | 168 __ j(zero, miss_label); |
168 } else { | 169 } else { |
169 // Give up probing if still not found the undefined value. | 170 // Give up probing if still not found the undefined value. |
170 __ j(not_equal, miss_label); | 171 __ j(not_equal, miss_label); |
171 } | 172 } |
172 } | 173 } |
173 | 174 |
174 __ bind(&done); | 175 __ bind(&done); |
175 __ DecrementCounter(&Counters::negative_lookups_miss, 1); | 176 __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1); |
176 } | 177 } |
177 | 178 |
178 | 179 |
179 void StubCache::GenerateProbe(MacroAssembler* masm, | 180 void StubCache::GenerateProbe(MacroAssembler* masm, |
180 Code::Flags flags, | 181 Code::Flags flags, |
181 Register receiver, | 182 Register receiver, |
182 Register name, | 183 Register name, |
183 Register scratch, | 184 Register scratch, |
184 Register extra, | 185 Register extra, |
185 Register extra2) { | 186 Register extra2) { |
| 187 Isolate* isolate = Isolate::Current(); |
186 Label miss; | 188 Label miss; |
187 USE(extra); // The register extra is not used on the X64 platform. | 189 USE(extra); // The register extra is not used on the X64 platform. |
188 USE(extra2); // The register extra2 is not used on the X64 platform. | 190 USE(extra2); // The register extra2 is not used on the X64 platform. |
189 // Make sure that code is valid. The shifting code relies on the | 191 // Make sure that code is valid. The shifting code relies on the |
190 // entry size being 16. | 192 // entry size being 16. |
191 ASSERT(sizeof(Entry) == 16); | 193 ASSERT(sizeof(Entry) == 16); |
192 | 194 |
193 // Make sure the flags do not name a specific type. | 195 // Make sure the flags do not name a specific type. |
194 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 196 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); |
195 | 197 |
196 // Make sure that there are no register conflicts. | 198 // Make sure that there are no register conflicts. |
197 ASSERT(!scratch.is(receiver)); | 199 ASSERT(!scratch.is(receiver)); |
198 ASSERT(!scratch.is(name)); | 200 ASSERT(!scratch.is(name)); |
199 | 201 |
200 // Check scratch register is valid, extra and extra2 are unused. | 202 // Check scratch register is valid, extra and extra2 are unused. |
201 ASSERT(!scratch.is(no_reg)); | 203 ASSERT(!scratch.is(no_reg)); |
202 ASSERT(extra2.is(no_reg)); | 204 ASSERT(extra2.is(no_reg)); |
203 | 205 |
204 // Check that the receiver isn't a smi. | 206 // Check that the receiver isn't a smi. |
205 __ JumpIfSmi(receiver, &miss); | 207 __ JumpIfSmi(receiver, &miss); |
206 | 208 |
207 // Get the map of the receiver and compute the hash. | 209 // Get the map of the receiver and compute the hash. |
208 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); | 210 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); |
209 // Use only the low 32 bits of the map pointer. | 211 // Use only the low 32 bits of the map pointer. |
210 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 212 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
211 __ xor_(scratch, Immediate(flags)); | 213 __ xor_(scratch, Immediate(flags)); |
212 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 214 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
213 | 215 |
214 // Probe the primary table. | 216 // Probe the primary table. |
215 ProbeTable(masm, flags, kPrimary, name, scratch); | 217 ProbeTable(isolate, masm, flags, kPrimary, name, scratch); |
216 | 218 |
217 // Primary miss: Compute hash for secondary probe. | 219 // Primary miss: Compute hash for secondary probe. |
218 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); | 220 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); |
219 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 221 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
220 __ xor_(scratch, Immediate(flags)); | 222 __ xor_(scratch, Immediate(flags)); |
221 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 223 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
222 __ subl(scratch, name); | 224 __ subl(scratch, name); |
223 __ addl(scratch, Immediate(flags)); | 225 __ addl(scratch, Immediate(flags)); |
224 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); | 226 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); |
225 | 227 |
226 // Probe the secondary table. | 228 // Probe the secondary table. |
227 ProbeTable(masm, flags, kSecondary, name, scratch); | 229 ProbeTable(isolate, masm, flags, kSecondary, name, scratch); |
228 | 230 |
229 // Cache miss: Fall-through and let caller handle the miss by | 231 // Cache miss: Fall-through and let caller handle the miss by |
230 // entering the runtime system. | 232 // entering the runtime system. |
231 __ bind(&miss); | 233 __ bind(&miss); |
232 } | 234 } |
233 | 235 |
234 | 236 |
235 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 237 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, |
236 int index, | 238 int index, |
237 Register prototype) { | 239 Register prototype) { |
238 // Load the global or builtins object from the current context. | 240 // Load the global or builtins object from the current context. |
239 __ movq(prototype, | 241 __ movq(prototype, |
240 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 242 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
241 // Load the global context from the global or builtins object. | 243 // Load the global context from the global or builtins object. |
242 __ movq(prototype, | 244 __ movq(prototype, |
243 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); | 245 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); |
244 // Load the function from the global context. | 246 // Load the function from the global context. |
245 __ movq(prototype, Operand(prototype, Context::SlotOffset(index))); | 247 __ movq(prototype, Operand(prototype, Context::SlotOffset(index))); |
246 // Load the initial map. The global functions all have initial maps. | 248 // Load the initial map. The global functions all have initial maps. |
247 __ movq(prototype, | 249 __ movq(prototype, |
248 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); | 250 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); |
249 // Load the prototype from the initial map. | 251 // Load the prototype from the initial map. |
250 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 252 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
251 } | 253 } |
252 | 254 |
253 | 255 |
254 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( | 256 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( |
255 MacroAssembler* masm, int index, Register prototype, Label* miss) { | 257 MacroAssembler* masm, int index, Register prototype, Label* miss) { |
256 // Check we're still in the same context. | 258 // Check we're still in the same context. |
257 __ Move(prototype, Top::global()); | 259 __ Move(prototype, Isolate::Current()->global()); |
258 __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)), | 260 __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)), |
259 prototype); | 261 prototype); |
260 __ j(not_equal, miss); | 262 __ j(not_equal, miss); |
261 // Get the global function with the given index. | 263 // Get the global function with the given index. |
262 JSFunction* function = JSFunction::cast(Top::global_context()->get(index)); | 264 JSFunction* function = JSFunction::cast( |
| 265 Isolate::Current()->global_context()->get(index)); |
263 // Load its initial map. The global functions all have initial maps. | 266 // Load its initial map. The global functions all have initial maps. |
264 __ Move(prototype, Handle<Map>(function->initial_map())); | 267 __ Move(prototype, Handle<Map>(function->initial_map())); |
265 // Load the prototype from the initial map. | 268 // Load the prototype from the initial map. |
266 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 269 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
267 } | 270 } |
268 | 271 |
269 | 272 |
270 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 273 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
271 Register receiver, | 274 Register receiver, |
272 Register scratch, | 275 Register scratch, |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 } | 371 } |
369 | 372 |
370 | 373 |
371 static void PushInterceptorArguments(MacroAssembler* masm, | 374 static void PushInterceptorArguments(MacroAssembler* masm, |
372 Register receiver, | 375 Register receiver, |
373 Register holder, | 376 Register holder, |
374 Register name, | 377 Register name, |
375 JSObject* holder_obj) { | 378 JSObject* holder_obj) { |
376 __ push(name); | 379 __ push(name); |
377 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); | 380 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); |
378 ASSERT(!Heap::InNewSpace(interceptor)); | 381 ASSERT(!HEAP->InNewSpace(interceptor)); |
379 __ Move(kScratchRegister, Handle<Object>(interceptor)); | 382 __ Move(kScratchRegister, Handle<Object>(interceptor)); |
380 __ push(kScratchRegister); | 383 __ push(kScratchRegister); |
381 __ push(receiver); | 384 __ push(receiver); |
382 __ push(holder); | 385 __ push(holder); |
383 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); | 386 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); |
384 } | 387 } |
385 | 388 |
386 | 389 |
387 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, | 390 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, |
388 Register receiver, | 391 Register receiver, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // ----------------------------------- | 462 // ----------------------------------- |
460 // Get the function and setup the context. | 463 // Get the function and setup the context. |
461 JSFunction* function = optimization.constant_function(); | 464 JSFunction* function = optimization.constant_function(); |
462 __ Move(rdi, Handle<JSFunction>(function)); | 465 __ Move(rdi, Handle<JSFunction>(function)); |
463 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 466 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
464 | 467 |
465 // Pass the additional arguments. | 468 // Pass the additional arguments. |
466 __ movq(Operand(rsp, 2 * kPointerSize), rdi); | 469 __ movq(Operand(rsp, 2 * kPointerSize), rdi); |
467 Object* call_data = optimization.api_call_info()->data(); | 470 Object* call_data = optimization.api_call_info()->data(); |
468 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); | 471 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); |
469 if (Heap::InNewSpace(call_data)) { | 472 if (HEAP->InNewSpace(call_data)) { |
470 __ Move(rcx, api_call_info_handle); | 473 __ Move(rcx, api_call_info_handle); |
471 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); | 474 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); |
472 __ movq(Operand(rsp, 3 * kPointerSize), rbx); | 475 __ movq(Operand(rsp, 3 * kPointerSize), rbx); |
473 } else { | 476 } else { |
474 __ Move(Operand(rsp, 3 * kPointerSize), Handle<Object>(call_data)); | 477 __ Move(Operand(rsp, 3 * kPointerSize), Handle<Object>(call_data)); |
475 } | 478 } |
476 | 479 |
477 // Prepare arguments. | 480 // Prepare arguments. |
478 __ lea(rbx, Operand(rsp, 3 * kPointerSize)); | 481 __ lea(rbx, Operand(rsp, 3 * kPointerSize)); |
479 | 482 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 } else { | 557 } else { |
555 CompileRegular(masm, | 558 CompileRegular(masm, |
556 object, | 559 object, |
557 receiver, | 560 receiver, |
558 scratch1, | 561 scratch1, |
559 scratch2, | 562 scratch2, |
560 scratch3, | 563 scratch3, |
561 name, | 564 name, |
562 holder, | 565 holder, |
563 miss); | 566 miss); |
564 return Heap::undefined_value(); // Success. | 567 return HEAP->undefined_value(); // Success. |
565 } | 568 } |
566 } | 569 } |
567 | 570 |
568 private: | 571 private: |
569 MaybeObject* CompileCacheable(MacroAssembler* masm, | 572 MaybeObject* CompileCacheable(MacroAssembler* masm, |
570 JSObject* object, | 573 JSObject* object, |
571 Register receiver, | 574 Register receiver, |
572 Register scratch1, | 575 Register scratch1, |
573 Register scratch2, | 576 Register scratch2, |
574 Register scratch3, | 577 Register scratch3, |
(...skipping 15 matching lines...) Expand all Loading... |
590 interceptor_holder); | 593 interceptor_holder); |
591 if (depth1 == kInvalidProtoDepth) { | 594 if (depth1 == kInvalidProtoDepth) { |
592 depth2 = | 595 depth2 = |
593 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, | 596 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, |
594 lookup->holder()); | 597 lookup->holder()); |
595 } | 598 } |
596 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || | 599 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || |
597 (depth2 != kInvalidProtoDepth); | 600 (depth2 != kInvalidProtoDepth); |
598 } | 601 } |
599 | 602 |
600 __ IncrementCounter(&Counters::call_const_interceptor, 1); | 603 __ IncrementCounter(COUNTERS->call_const_interceptor(), 1); |
601 | 604 |
602 if (can_do_fast_api_call) { | 605 if (can_do_fast_api_call) { |
603 __ IncrementCounter(&Counters::call_const_interceptor_fast_api, 1); | 606 __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1); |
604 ReserveSpaceForFastApiCall(masm, scratch1); | 607 ReserveSpaceForFastApiCall(masm, scratch1); |
605 } | 608 } |
606 | 609 |
607 // Check that the maps from receiver to interceptor's holder | 610 // Check that the maps from receiver to interceptor's holder |
608 // haven't changed and thus we can invoke interceptor. | 611 // haven't changed and thus we can invoke interceptor. |
609 Label miss_cleanup; | 612 Label miss_cleanup; |
610 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 613 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
611 Register holder = | 614 Register holder = |
612 stub_compiler_->CheckPrototypes(object, receiver, | 615 stub_compiler_->CheckPrototypes(object, receiver, |
613 interceptor_holder, scratch1, | 616 interceptor_holder, scratch1, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 FreeSpaceForFastApiCall(masm, scratch1); | 656 FreeSpaceForFastApiCall(masm, scratch1); |
654 __ jmp(miss_label); | 657 __ jmp(miss_label); |
655 } | 658 } |
656 | 659 |
657 // Invoke a regular function. | 660 // Invoke a regular function. |
658 __ bind(®ular_invoke); | 661 __ bind(®ular_invoke); |
659 if (can_do_fast_api_call) { | 662 if (can_do_fast_api_call) { |
660 FreeSpaceForFastApiCall(masm, scratch1); | 663 FreeSpaceForFastApiCall(masm, scratch1); |
661 } | 664 } |
662 | 665 |
663 return Heap::undefined_value(); // Success. | 666 return HEAP->undefined_value(); // Success. |
664 } | 667 } |
665 | 668 |
666 void CompileRegular(MacroAssembler* masm, | 669 void CompileRegular(MacroAssembler* masm, |
667 JSObject* object, | 670 JSObject* object, |
668 Register receiver, | 671 Register receiver, |
669 Register scratch1, | 672 Register scratch1, |
670 Register scratch2, | 673 Register scratch2, |
671 Register scratch3, | 674 Register scratch3, |
672 String* name, | 675 String* name, |
673 JSObject* interceptor_holder, | 676 JSObject* interceptor_holder, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 StubCompiler* stub_compiler_; | 725 StubCompiler* stub_compiler_; |
723 const ParameterCount& arguments_; | 726 const ParameterCount& arguments_; |
724 Register name_; | 727 Register name_; |
725 }; | 728 }; |
726 | 729 |
727 | 730 |
728 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 731 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
729 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 732 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
730 Code* code = NULL; | 733 Code* code = NULL; |
731 if (kind == Code::LOAD_IC) { | 734 if (kind == Code::LOAD_IC) { |
732 code = Builtins::builtin(Builtins::LoadIC_Miss); | 735 code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss); |
733 } else { | 736 } else { |
734 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 737 code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss); |
735 } | 738 } |
736 | 739 |
737 Handle<Code> ic(code); | 740 Handle<Code> ic(code); |
738 __ Jump(ic, RelocInfo::CODE_TARGET); | 741 __ Jump(ic, RelocInfo::CODE_TARGET); |
739 } | 742 } |
740 | 743 |
741 | 744 |
742 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 745 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
743 // but may be destroyed if store is successful. | 746 // but may be destroyed if store is successful. |
744 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 747 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 Register scratch, | 832 Register scratch, |
830 Label* miss) { | 833 Label* miss) { |
831 Object* probe; | 834 Object* probe; |
832 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 835 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
833 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 836 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
834 } | 837 } |
835 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 838 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
836 ASSERT(cell->value()->IsTheHole()); | 839 ASSERT(cell->value()->IsTheHole()); |
837 __ Move(scratch, Handle<Object>(cell)); | 840 __ Move(scratch, Handle<Object>(cell)); |
838 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 841 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
839 Factory::the_hole_value()); | 842 FACTORY->the_hole_value()); |
840 __ j(not_equal, miss); | 843 __ j(not_equal, miss); |
841 return cell; | 844 return cell; |
842 } | 845 } |
843 | 846 |
844 | 847 |
845 #undef __ | 848 #undef __ |
846 #define __ ACCESS_MASM((masm())) | 849 #define __ ACCESS_MASM((masm())) |
847 | 850 |
848 | 851 |
849 Register StubCompiler::CheckPrototypes(JSObject* object, | 852 Register StubCompiler::CheckPrototypes(JSObject* object, |
(...skipping 28 matching lines...) Expand all Loading... |
878 | 881 |
879 // Only global objects and objects that do not require access | 882 // Only global objects and objects that do not require access |
880 // checks are allowed in stubs. | 883 // checks are allowed in stubs. |
881 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 884 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
882 | 885 |
883 JSObject* prototype = JSObject::cast(current->GetPrototype()); | 886 JSObject* prototype = JSObject::cast(current->GetPrototype()); |
884 if (!current->HasFastProperties() && | 887 if (!current->HasFastProperties() && |
885 !current->IsJSGlobalObject() && | 888 !current->IsJSGlobalObject() && |
886 !current->IsJSGlobalProxy()) { | 889 !current->IsJSGlobalProxy()) { |
887 if (!name->IsSymbol()) { | 890 if (!name->IsSymbol()) { |
888 MaybeObject* lookup_result = Heap::LookupSymbol(name); | 891 MaybeObject* lookup_result = HEAP->LookupSymbol(name); |
889 if (lookup_result->IsFailure()) { | 892 if (lookup_result->IsFailure()) { |
890 set_failure(Failure::cast(lookup_result)); | 893 set_failure(Failure::cast(lookup_result)); |
891 return reg; | 894 return reg; |
892 } else { | 895 } else { |
893 name = String::cast(lookup_result->ToObjectUnchecked()); | 896 name = String::cast(lookup_result->ToObjectUnchecked()); |
894 } | 897 } |
895 } | 898 } |
896 ASSERT(current->property_dictionary()->FindEntry(name) == | 899 ASSERT(current->property_dictionary()->FindEntry(name) == |
897 StringDictionary::kNotFound); | 900 StringDictionary::kNotFound); |
898 | 901 |
899 GenerateDictionaryNegativeLookup(masm(), | 902 GenerateDictionaryNegativeLookup(masm(), |
900 miss, | 903 miss, |
901 reg, | 904 reg, |
902 name, | 905 name, |
903 scratch1, | 906 scratch1, |
904 scratch2); | 907 scratch2); |
905 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 908 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
906 reg = holder_reg; // from now the object is in holder_reg | 909 reg = holder_reg; // from now the object is in holder_reg |
907 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 910 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
908 } else if (Heap::InNewSpace(prototype)) { | 911 } else if (HEAP->InNewSpace(prototype)) { |
909 // Get the map of the current object. | 912 // Get the map of the current object. |
910 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 913 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
911 __ Cmp(scratch1, Handle<Map>(current->map())); | 914 __ Cmp(scratch1, Handle<Map>(current->map())); |
912 // Branch on the result of the map check. | 915 // Branch on the result of the map check. |
913 __ j(not_equal, miss); | 916 __ j(not_equal, miss); |
914 // Check access rights to the global object. This has to happen | 917 // Check access rights to the global object. This has to happen |
915 // after the map check so that we know that the object is | 918 // after the map check so that we know that the object is |
916 // actually a global object. | 919 // actually a global object. |
917 if (current->IsJSGlobalProxy()) { | 920 if (current->IsJSGlobalProxy()) { |
918 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 921 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
(...skipping 30 matching lines...) Expand all Loading... |
949 | 952 |
950 // Go to the next object in the prototype chain. | 953 // Go to the next object in the prototype chain. |
951 current = prototype; | 954 current = prototype; |
952 } | 955 } |
953 | 956 |
954 // Check the holder map. | 957 // Check the holder map. |
955 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map())); | 958 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map())); |
956 __ j(not_equal, miss); | 959 __ j(not_equal, miss); |
957 | 960 |
958 // Log the check depth. | 961 // Log the check depth. |
959 LOG(IntEvent("check-maps-depth", depth + 1)); | 962 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
960 | 963 |
961 // Perform security check for access to the global object and return | 964 // Perform security check for access to the global object and return |
962 // the holder register. | 965 // the holder register. |
963 ASSERT(current == holder); | 966 ASSERT(current == holder); |
964 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 967 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
965 if (current->IsJSGlobalProxy()) { | 968 if (current->IsJSGlobalProxy()) { |
966 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 969 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
967 } | 970 } |
968 | 971 |
969 // If we've skipped any global objects, it's not enough to verify | 972 // If we've skipped any global objects, it's not enough to verify |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 scratch2, scratch3, name, miss); | 1035 scratch2, scratch3, name, miss); |
1033 | 1036 |
1034 Handle<AccessorInfo> callback_handle(callback); | 1037 Handle<AccessorInfo> callback_handle(callback); |
1035 | 1038 |
1036 // Insert additional parameters into the stack frame above return address. | 1039 // Insert additional parameters into the stack frame above return address. |
1037 ASSERT(!scratch2.is(reg)); | 1040 ASSERT(!scratch2.is(reg)); |
1038 __ pop(scratch2); // Get return address to place it below. | 1041 __ pop(scratch2); // Get return address to place it below. |
1039 | 1042 |
1040 __ push(receiver); // receiver | 1043 __ push(receiver); // receiver |
1041 __ push(reg); // holder | 1044 __ push(reg); // holder |
1042 if (Heap::InNewSpace(callback_handle->data())) { | 1045 if (HEAP->InNewSpace(callback_handle->data())) { |
1043 __ Move(scratch1, callback_handle); | 1046 __ Move(scratch1, callback_handle); |
1044 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); // data | 1047 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); // data |
1045 } else { | 1048 } else { |
1046 __ Push(Handle<Object>(callback_handle->data())); | 1049 __ Push(Handle<Object>(callback_handle->data())); |
1047 } | 1050 } |
1048 __ push(name_reg); // name | 1051 __ push(name_reg); // name |
1049 // Save a pointer to where we pushed the arguments pointer. | 1052 // Save a pointer to where we pushed the arguments pointer. |
1050 // This will be passed as the const AccessorInfo& to the C++ callback. | 1053 // This will be passed as the const AccessorInfo& to the C++ callback. |
1051 | 1054 |
1052 #ifdef _WIN64 | 1055 #ifdef _WIN64 |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 | 1287 |
1285 | 1288 |
1286 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, | 1289 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, |
1287 JSFunction* function, | 1290 JSFunction* function, |
1288 Label* miss) { | 1291 Label* miss) { |
1289 // Get the value from the cell. | 1292 // Get the value from the cell. |
1290 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); | 1293 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); |
1291 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); | 1294 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); |
1292 | 1295 |
1293 // Check that the cell contains the same function. | 1296 // Check that the cell contains the same function. |
1294 if (Heap::InNewSpace(function)) { | 1297 if (HEAP->InNewSpace(function)) { |
1295 // We can't embed a pointer to a function in new space so we have | 1298 // We can't embed a pointer to a function in new space so we have |
1296 // to verify that the shared function info is unchanged. This has | 1299 // to verify that the shared function info is unchanged. This has |
1297 // the nice side effect that multiple closures based on the same | 1300 // the nice side effect that multiple closures based on the same |
1298 // function can all use this call IC. Before we load through the | 1301 // function can all use this call IC. Before we load through the |
1299 // function, we have to verify that it still is a function. | 1302 // function, we have to verify that it still is a function. |
1300 __ JumpIfSmi(rdi, miss); | 1303 __ JumpIfSmi(rdi, miss); |
1301 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); | 1304 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); |
1302 __ j(not_equal, miss); | 1305 __ j(not_equal, miss); |
1303 | 1306 |
1304 // Check the shared function info. Make sure it hasn't changed. | 1307 // Check the shared function info. Make sure it hasn't changed. |
1305 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | 1308 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); |
1306 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | 1309 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); |
1307 __ j(not_equal, miss); | 1310 __ j(not_equal, miss); |
1308 } else { | 1311 } else { |
1309 __ Cmp(rdi, Handle<JSFunction>(function)); | 1312 __ Cmp(rdi, Handle<JSFunction>(function)); |
1310 __ j(not_equal, miss); | 1313 __ j(not_equal, miss); |
1311 } | 1314 } |
1312 } | 1315 } |
1313 | 1316 |
1314 | 1317 |
1315 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1318 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
1316 MaybeObject* maybe_obj = StubCache::ComputeCallMiss(arguments().immediate(), | 1319 MaybeObject* maybe_obj = Isolate::Current()->stub_cache()->ComputeCallMiss( |
1317 kind_); | 1320 arguments().immediate(), kind_); |
1318 Object* obj; | 1321 Object* obj; |
1319 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1322 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1320 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1323 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1321 return obj; | 1324 return obj; |
1322 } | 1325 } |
1323 | 1326 |
1324 | 1327 |
1325 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1328 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, |
1326 JSObject* holder, | 1329 JSObject* holder, |
1327 int index, | 1330 int index, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 String* name) { | 1389 String* name) { |
1387 // ----------- S t a t e ------------- | 1390 // ----------- S t a t e ------------- |
1388 // -- rcx : name | 1391 // -- rcx : name |
1389 // -- rsp[0] : return address | 1392 // -- rsp[0] : return address |
1390 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1393 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1391 // -- ... | 1394 // -- ... |
1392 // -- rsp[(argc + 1) * 8] : receiver | 1395 // -- rsp[(argc + 1) * 8] : receiver |
1393 // ----------------------------------- | 1396 // ----------------------------------- |
1394 | 1397 |
1395 // If object is not an array, bail out to regular call. | 1398 // If object is not an array, bail out to regular call. |
1396 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); | 1399 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); |
1397 | 1400 |
1398 Label miss; | 1401 Label miss; |
1399 | 1402 |
1400 GenerateNameCheck(name, &miss); | 1403 GenerateNameCheck(name, &miss); |
1401 | 1404 |
1402 // Get the receiver from the stack. | 1405 // Get the receiver from the stack. |
1403 const int argc = arguments().immediate(); | 1406 const int argc = arguments().immediate(); |
1404 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1407 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1405 | 1408 |
1406 // Check that the receiver isn't a smi. | 1409 // Check that the receiver isn't a smi. |
(...skipping 13 matching lines...) Expand all Loading... |
1420 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); | 1423 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); |
1421 __ ret((argc + 1) * kPointerSize); | 1424 __ ret((argc + 1) * kPointerSize); |
1422 } else { | 1425 } else { |
1423 Label call_builtin; | 1426 Label call_builtin; |
1424 | 1427 |
1425 // Get the elements array of the object. | 1428 // Get the elements array of the object. |
1426 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); | 1429 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
1427 | 1430 |
1428 // Check that the elements are in fast mode and writable. | 1431 // Check that the elements are in fast mode and writable. |
1429 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 1432 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
1430 Factory::fixed_array_map()); | 1433 FACTORY->fixed_array_map()); |
1431 __ j(not_equal, &call_builtin); | 1434 __ j(not_equal, &call_builtin); |
1432 | 1435 |
1433 if (argc == 1) { // Otherwise fall through to call builtin. | 1436 if (argc == 1) { // Otherwise fall through to call builtin. |
1434 Label exit, with_write_barrier, attempt_to_grow_elements; | 1437 Label exit, with_write_barrier, attempt_to_grow_elements; |
1435 | 1438 |
1436 // Get the array's length into rax and calculate new length. | 1439 // Get the array's length into rax and calculate new length. |
1437 __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); | 1440 __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); |
1438 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); | 1441 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); |
1439 __ addl(rax, Immediate(argc)); | 1442 __ addl(rax, Immediate(argc)); |
1440 | 1443 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 String* name) { | 1552 String* name) { |
1550 // ----------- S t a t e ------------- | 1553 // ----------- S t a t e ------------- |
1551 // -- rcx : name | 1554 // -- rcx : name |
1552 // -- rsp[0] : return address | 1555 // -- rsp[0] : return address |
1553 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1556 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1554 // -- ... | 1557 // -- ... |
1555 // -- rsp[(argc + 1) * 8] : receiver | 1558 // -- rsp[(argc + 1) * 8] : receiver |
1556 // ----------------------------------- | 1559 // ----------------------------------- |
1557 | 1560 |
1558 // If object is not an array, bail out to regular call. | 1561 // If object is not an array, bail out to regular call. |
1559 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); | 1562 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); |
1560 | 1563 |
1561 Label miss, return_undefined, call_builtin; | 1564 Label miss, return_undefined, call_builtin; |
1562 | 1565 |
1563 GenerateNameCheck(name, &miss); | 1566 GenerateNameCheck(name, &miss); |
1564 | 1567 |
1565 // Get the receiver from the stack. | 1568 // Get the receiver from the stack. |
1566 const int argc = arguments().immediate(); | 1569 const int argc = arguments().immediate(); |
1567 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1570 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1568 | 1571 |
1569 // Check that the receiver isn't a smi. | 1572 // Check that the receiver isn't a smi. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1634 String* name) { | 1637 String* name) { |
1635 // ----------- S t a t e ------------- | 1638 // ----------- S t a t e ------------- |
1636 // -- rcx : function name | 1639 // -- rcx : function name |
1637 // -- rsp[0] : return address | 1640 // -- rsp[0] : return address |
1638 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1641 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1639 // -- ... | 1642 // -- ... |
1640 // -- rsp[(argc + 1) * 8] : receiver | 1643 // -- rsp[(argc + 1) * 8] : receiver |
1641 // ----------------------------------- | 1644 // ----------------------------------- |
1642 | 1645 |
1643 // If object is not a string, bail out to regular call. | 1646 // If object is not a string, bail out to regular call. |
1644 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1647 if (!object->IsString() || cell != NULL) return HEAP->undefined_value(); |
1645 | 1648 |
1646 const int argc = arguments().immediate(); | 1649 const int argc = arguments().immediate(); |
1647 | 1650 |
1648 Label miss; | 1651 Label miss; |
1649 Label name_miss; | 1652 Label name_miss; |
1650 Label index_out_of_range; | 1653 Label index_out_of_range; |
1651 Label* index_out_of_range_label = &index_out_of_range; | 1654 Label* index_out_of_range_label = &index_out_of_range; |
1652 | 1655 |
1653 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { | 1656 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
1654 index_out_of_range_label = &miss; | 1657 index_out_of_range_label = &miss; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 String* name) { | 1721 String* name) { |
1719 // ----------- S t a t e ------------- | 1722 // ----------- S t a t e ------------- |
1720 // -- rcx : function name | 1723 // -- rcx : function name |
1721 // -- rsp[0] : return address | 1724 // -- rsp[0] : return address |
1722 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1725 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1723 // -- ... | 1726 // -- ... |
1724 // -- rsp[(argc + 1) * 8] : receiver | 1727 // -- rsp[(argc + 1) * 8] : receiver |
1725 // ----------------------------------- | 1728 // ----------------------------------- |
1726 | 1729 |
1727 // If object is not a string, bail out to regular call. | 1730 // If object is not a string, bail out to regular call. |
1728 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1731 if (!object->IsString() || cell != NULL) return HEAP->undefined_value(); |
1729 | 1732 |
1730 const int argc = arguments().immediate(); | 1733 const int argc = arguments().immediate(); |
1731 | 1734 |
1732 Label miss; | 1735 Label miss; |
1733 Label name_miss; | 1736 Label name_miss; |
1734 Label index_out_of_range; | 1737 Label index_out_of_range; |
1735 Label* index_out_of_range_label = &index_out_of_range; | 1738 Label* index_out_of_range_label = &index_out_of_range; |
1736 | 1739 |
1737 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { | 1740 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
1738 index_out_of_range_label = &miss; | 1741 index_out_of_range_label = &miss; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 // -- rsp[0] : return address | 1810 // -- rsp[0] : return address |
1808 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1811 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1809 // -- ... | 1812 // -- ... |
1810 // -- rsp[(argc + 1) * 8] : receiver | 1813 // -- rsp[(argc + 1) * 8] : receiver |
1811 // ----------------------------------- | 1814 // ----------------------------------- |
1812 | 1815 |
1813 const int argc = arguments().immediate(); | 1816 const int argc = arguments().immediate(); |
1814 | 1817 |
1815 // If the object is not a JSObject or we got an unexpected number of | 1818 // If the object is not a JSObject or we got an unexpected number of |
1816 // arguments, bail out to the regular call. | 1819 // arguments, bail out to the regular call. |
1817 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); | 1820 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); |
1818 | 1821 |
1819 Label miss; | 1822 Label miss; |
1820 GenerateNameCheck(name, &miss); | 1823 GenerateNameCheck(name, &miss); |
1821 | 1824 |
1822 if (cell == NULL) { | 1825 if (cell == NULL) { |
1823 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 1826 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1824 | 1827 |
1825 __ JumpIfSmi(rdx, &miss); | 1828 __ JumpIfSmi(rdx, &miss); |
1826 | 1829 |
1827 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | 1830 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 1869 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
1867 } | 1870 } |
1868 | 1871 |
1869 | 1872 |
1870 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 1873 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
1871 JSObject* holder, | 1874 JSObject* holder, |
1872 JSGlobalPropertyCell* cell, | 1875 JSGlobalPropertyCell* cell, |
1873 JSFunction* function, | 1876 JSFunction* function, |
1874 String* name) { | 1877 String* name) { |
1875 // TODO(872): implement this. | 1878 // TODO(872): implement this. |
1876 return Heap::undefined_value(); | 1879 return HEAP->undefined_value(); |
1877 } | 1880 } |
1878 | 1881 |
1879 | 1882 |
1880 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 1883 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
1881 JSObject* holder, | 1884 JSObject* holder, |
1882 JSGlobalPropertyCell* cell, | 1885 JSGlobalPropertyCell* cell, |
1883 JSFunction* function, | 1886 JSFunction* function, |
1884 String* name) { | 1887 String* name) { |
1885 // ----------- S t a t e ------------- | 1888 // ----------- S t a t e ------------- |
1886 // -- rcx : function name | 1889 // -- rcx : function name |
1887 // -- rsp[0] : return address | 1890 // -- rsp[0] : return address |
1888 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1891 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1889 // -- ... | 1892 // -- ... |
1890 // -- rsp[(argc + 1) * 8] : receiver | 1893 // -- rsp[(argc + 1) * 8] : receiver |
1891 // ----------------------------------- | 1894 // ----------------------------------- |
1892 | 1895 |
1893 const int argc = arguments().immediate(); | 1896 const int argc = arguments().immediate(); |
1894 | 1897 |
1895 // If the object is not a JSObject or we got an unexpected number of | 1898 // If the object is not a JSObject or we got an unexpected number of |
1896 // arguments, bail out to the regular call. | 1899 // arguments, bail out to the regular call. |
1897 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); | 1900 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); |
1898 | 1901 |
1899 Label miss; | 1902 Label miss; |
1900 GenerateNameCheck(name, &miss); | 1903 GenerateNameCheck(name, &miss); |
1901 | 1904 |
1902 if (cell == NULL) { | 1905 if (cell == NULL) { |
1903 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 1906 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1904 | 1907 |
1905 __ JumpIfSmi(rdx, &miss); | 1908 __ JumpIfSmi(rdx, &miss); |
1906 | 1909 |
1907 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | 1910 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, |
(...skipping 28 matching lines...) Expand all Loading... |
1936 // This only happens for the most negative smi. | 1939 // This only happens for the most negative smi. |
1937 Label slow; | 1940 Label slow; |
1938 __ j(negative, &slow); | 1941 __ j(negative, &slow); |
1939 | 1942 |
1940 // Smi case done. | 1943 // Smi case done. |
1941 __ Integer32ToSmi(rax, rax); | 1944 __ Integer32ToSmi(rax, rax); |
1942 __ ret(2 * kPointerSize); | 1945 __ ret(2 * kPointerSize); |
1943 | 1946 |
1944 // Check if the argument is a heap number and load its value. | 1947 // Check if the argument is a heap number and load its value. |
1945 __ bind(¬_smi); | 1948 __ bind(¬_smi); |
1946 __ CheckMap(rax, Factory::heap_number_map(), &slow, true); | 1949 __ CheckMap(rax, FACTORY->heap_number_map(), &slow, true); |
1947 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); | 1950 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); |
1948 | 1951 |
1949 // Check the sign of the argument. If the argument is positive, | 1952 // Check the sign of the argument. If the argument is positive, |
1950 // just return it. | 1953 // just return it. |
1951 Label negative_sign; | 1954 Label negative_sign; |
1952 const int sign_mask_shift = | 1955 const int sign_mask_shift = |
1953 (HeapNumber::kExponentOffset - HeapNumber::kValueOffset) * kBitsPerByte; | 1956 (HeapNumber::kExponentOffset - HeapNumber::kValueOffset) * kBitsPerByte; |
1954 __ movq(rdi, static_cast<int64_t>(HeapNumber::kSignMask) << sign_mask_shift, | 1957 __ movq(rdi, static_cast<int64_t>(HeapNumber::kSignMask) << sign_mask_shift, |
1955 RelocInfo::NONE); | 1958 RelocInfo::NONE); |
1956 __ testq(rbx, rdi); | 1959 __ testq(rbx, rdi); |
(...skipping 28 matching lines...) Expand all Loading... |
1985 MaybeObject* CallStubCompiler::CompileFastApiCall( | 1988 MaybeObject* CallStubCompiler::CompileFastApiCall( |
1986 const CallOptimization& optimization, | 1989 const CallOptimization& optimization, |
1987 Object* object, | 1990 Object* object, |
1988 JSObject* holder, | 1991 JSObject* holder, |
1989 JSGlobalPropertyCell* cell, | 1992 JSGlobalPropertyCell* cell, |
1990 JSFunction* function, | 1993 JSFunction* function, |
1991 String* name) { | 1994 String* name) { |
1992 ASSERT(optimization.is_simple_api_call()); | 1995 ASSERT(optimization.is_simple_api_call()); |
1993 // Bail out if object is a global object as we don't want to | 1996 // Bail out if object is a global object as we don't want to |
1994 // repatch it to global receiver. | 1997 // repatch it to global receiver. |
1995 if (object->IsGlobalObject()) return Heap::undefined_value(); | 1998 if (object->IsGlobalObject()) return HEAP->undefined_value(); |
1996 if (cell != NULL) return Heap::undefined_value(); | 1999 if (cell != NULL) return HEAP->undefined_value(); |
1997 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2000 int depth = optimization.GetPrototypeDepthOfExpectedType( |
1998 JSObject::cast(object), holder); | 2001 JSObject::cast(object), holder); |
1999 if (depth == kInvalidProtoDepth) return Heap::undefined_value(); | 2002 if (depth == kInvalidProtoDepth) return HEAP->undefined_value(); |
2000 | 2003 |
2001 Label miss, miss_before_stack_reserved; | 2004 Label miss, miss_before_stack_reserved; |
2002 | 2005 |
2003 GenerateNameCheck(name, &miss_before_stack_reserved); | 2006 GenerateNameCheck(name, &miss_before_stack_reserved); |
2004 | 2007 |
2005 // Get the receiver from the stack. | 2008 // Get the receiver from the stack. |
2006 const int argc = arguments().immediate(); | 2009 const int argc = arguments().immediate(); |
2007 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2010 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2008 | 2011 |
2009 // Check that the receiver isn't a smi. | 2012 // Check that the receiver isn't a smi. |
2010 __ JumpIfSmi(rdx, &miss_before_stack_reserved); | 2013 __ JumpIfSmi(rdx, &miss_before_stack_reserved); |
2011 | 2014 |
2012 __ IncrementCounter(&Counters::call_const, 1); | 2015 __ IncrementCounter(COUNTERS->call_const(), 1); |
2013 __ IncrementCounter(&Counters::call_const_fast_api, 1); | 2016 __ IncrementCounter(COUNTERS->call_const_fast_api(), 1); |
2014 | 2017 |
2015 // Allocate space for v8::Arguments implicit values. Must be initialized | 2018 // Allocate space for v8::Arguments implicit values. Must be initialized |
2016 // before calling any runtime function. | 2019 // before calling any runtime function. |
2017 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2020 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |
2018 | 2021 |
2019 // Check that the maps haven't changed and find a Holder as a side effect. | 2022 // Check that the maps haven't changed and find a Holder as a side effect. |
2020 CheckPrototypes(JSObject::cast(object), rdx, holder, | 2023 CheckPrototypes(JSObject::cast(object), rdx, holder, |
2021 rbx, rax, rdi, name, depth, &miss); | 2024 rbx, rax, rdi, name, depth, &miss); |
2022 | 2025 |
2023 // Move the return address on top of the stack. | 2026 // Move the return address on top of the stack. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 __ JumpIfSmi(rdx, &miss); | 2081 __ JumpIfSmi(rdx, &miss); |
2079 } | 2082 } |
2080 | 2083 |
2081 // Make sure that it's okay not to patch the on stack receiver | 2084 // Make sure that it's okay not to patch the on stack receiver |
2082 // unless we're doing a receiver map check. | 2085 // unless we're doing a receiver map check. |
2083 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2086 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2084 | 2087 |
2085 SharedFunctionInfo* function_info = function->shared(); | 2088 SharedFunctionInfo* function_info = function->shared(); |
2086 switch (check) { | 2089 switch (check) { |
2087 case RECEIVER_MAP_CHECK: | 2090 case RECEIVER_MAP_CHECK: |
2088 __ IncrementCounter(&Counters::call_const, 1); | 2091 __ IncrementCounter(COUNTERS->call_const(), 1); |
2089 | 2092 |
2090 // Check that the maps haven't changed. | 2093 // Check that the maps haven't changed. |
2091 CheckPrototypes(JSObject::cast(object), rdx, holder, | 2094 CheckPrototypes(JSObject::cast(object), rdx, holder, |
2092 rbx, rax, rdi, name, &miss); | 2095 rbx, rax, rdi, name, &miss); |
2093 | 2096 |
2094 // Patch the receiver on the stack with the global proxy if | 2097 // Patch the receiver on the stack with the global proxy if |
2095 // necessary. | 2098 // necessary. |
2096 if (object->IsGlobalObject()) { | 2099 if (object->IsGlobalObject()) { |
2097 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2100 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2098 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2101 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2284 // Patch the receiver on the stack with the global proxy. | 2287 // Patch the receiver on the stack with the global proxy. |
2285 if (object->IsGlobalObject()) { | 2288 if (object->IsGlobalObject()) { |
2286 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2289 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2287 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2290 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
2288 } | 2291 } |
2289 | 2292 |
2290 // Setup the context (function already in rdi). | 2293 // Setup the context (function already in rdi). |
2291 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 2294 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
2292 | 2295 |
2293 // Jump to the cached code (tail call). | 2296 // Jump to the cached code (tail call). |
2294 __ IncrementCounter(&Counters::call_global_inline, 1); | 2297 __ IncrementCounter(COUNTERS->call_global_inline(), 1); |
2295 ASSERT(function->is_compiled()); | 2298 ASSERT(function->is_compiled()); |
2296 ParameterCount expected(function->shared()->formal_parameter_count()); | 2299 ParameterCount expected(function->shared()->formal_parameter_count()); |
2297 if (V8::UseCrankshaft()) { | 2300 if (V8::UseCrankshaft()) { |
2298 // TODO(kasperl): For now, we always call indirectly through the | 2301 // TODO(kasperl): For now, we always call indirectly through the |
2299 // code field in the function to allow recompilation to take effect | 2302 // code field in the function to allow recompilation to take effect |
2300 // without changing any of the call sites. | 2303 // without changing any of the call sites. |
2301 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2304 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
2302 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION); | 2305 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION); |
2303 } else { | 2306 } else { |
2304 Handle<Code> code(function->code()); | 2307 Handle<Code> code(function->code()); |
2305 __ InvokeCode(code, expected, arguments(), | 2308 __ InvokeCode(code, expected, arguments(), |
2306 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 2309 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
2307 } | 2310 } |
2308 // Handle call cache miss. | 2311 // Handle call cache miss. |
2309 __ bind(&miss); | 2312 __ bind(&miss); |
2310 __ IncrementCounter(&Counters::call_global_inline_miss, 1); | 2313 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1); |
2311 Object* obj; | 2314 Object* obj; |
2312 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2315 { MaybeObject* maybe_obj = GenerateMissBranch(); |
2313 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2316 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2314 } | 2317 } |
2315 | 2318 |
2316 // Return the generated code. | 2319 // Return the generated code. |
2317 return GetCode(NORMAL, name); | 2320 return GetCode(NORMAL, name); |
2318 } | 2321 } |
2319 | 2322 |
2320 | 2323 |
(...skipping 12 matching lines...) Expand all Loading... |
2333 // Generate store field code. Preserves receiver and name on jump to miss. | 2336 // Generate store field code. Preserves receiver and name on jump to miss. |
2334 GenerateStoreField(masm(), | 2337 GenerateStoreField(masm(), |
2335 object, | 2338 object, |
2336 index, | 2339 index, |
2337 transition, | 2340 transition, |
2338 rdx, rcx, rbx, | 2341 rdx, rcx, rbx, |
2339 &miss); | 2342 &miss); |
2340 | 2343 |
2341 // Handle store cache miss. | 2344 // Handle store cache miss. |
2342 __ bind(&miss); | 2345 __ bind(&miss); |
2343 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2346 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2347 Builtins::StoreIC_Miss)); |
2344 __ Jump(ic, RelocInfo::CODE_TARGET); | 2348 __ Jump(ic, RelocInfo::CODE_TARGET); |
2345 | 2349 |
2346 // Return the generated code. | 2350 // Return the generated code. |
2347 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2351 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2348 } | 2352 } |
2349 | 2353 |
2350 | 2354 |
2351 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2355 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, |
2352 AccessorInfo* callback, | 2356 AccessorInfo* callback, |
2353 String* name) { | 2357 String* name) { |
(...skipping 29 matching lines...) Expand all Loading... |
2383 __ push(rax); // value | 2387 __ push(rax); // value |
2384 __ push(rbx); // restore return address | 2388 __ push(rbx); // restore return address |
2385 | 2389 |
2386 // Do tail-call to the runtime system. | 2390 // Do tail-call to the runtime system. |
2387 ExternalReference store_callback_property = | 2391 ExternalReference store_callback_property = |
2388 ExternalReference(IC_Utility(IC::kStoreCallbackProperty)); | 2392 ExternalReference(IC_Utility(IC::kStoreCallbackProperty)); |
2389 __ TailCallExternalReference(store_callback_property, 4, 1); | 2393 __ TailCallExternalReference(store_callback_property, 4, 1); |
2390 | 2394 |
2391 // Handle store cache miss. | 2395 // Handle store cache miss. |
2392 __ bind(&miss); | 2396 __ bind(&miss); |
2393 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2397 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2398 Builtins::StoreIC_Miss)); |
2394 __ Jump(ic, RelocInfo::CODE_TARGET); | 2399 __ Jump(ic, RelocInfo::CODE_TARGET); |
2395 | 2400 |
2396 // Return the generated code. | 2401 // Return the generated code. |
2397 return GetCode(CALLBACKS, name); | 2402 return GetCode(CALLBACKS, name); |
2398 } | 2403 } |
2399 | 2404 |
2400 | 2405 |
2401 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2406 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, |
2402 String* name) { | 2407 String* name) { |
2403 // ----------- S t a t e ------------- | 2408 // ----------- S t a t e ------------- |
(...skipping 28 matching lines...) Expand all Loading... |
2432 __ Push(Smi::FromInt(strict_mode_)); | 2437 __ Push(Smi::FromInt(strict_mode_)); |
2433 __ push(rbx); // restore return address | 2438 __ push(rbx); // restore return address |
2434 | 2439 |
2435 // Do tail-call to the runtime system. | 2440 // Do tail-call to the runtime system. |
2436 ExternalReference store_ic_property = | 2441 ExternalReference store_ic_property = |
2437 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); | 2442 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); |
2438 __ TailCallExternalReference(store_ic_property, 4, 1); | 2443 __ TailCallExternalReference(store_ic_property, 4, 1); |
2439 | 2444 |
2440 // Handle store cache miss. | 2445 // Handle store cache miss. |
2441 __ bind(&miss); | 2446 __ bind(&miss); |
2442 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2447 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2448 Builtins::StoreIC_Miss)); |
2443 __ Jump(ic, RelocInfo::CODE_TARGET); | 2449 __ Jump(ic, RelocInfo::CODE_TARGET); |
2444 | 2450 |
2445 // Return the generated code. | 2451 // Return the generated code. |
2446 return GetCode(INTERCEPTOR, name); | 2452 return GetCode(INTERCEPTOR, name); |
2447 } | 2453 } |
2448 | 2454 |
2449 | 2455 |
2450 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2456 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, |
2451 JSGlobalPropertyCell* cell, | 2457 JSGlobalPropertyCell* cell, |
2452 String* name) { | 2458 String* name) { |
(...skipping 16 matching lines...) Expand all Loading... |
2469 // global object. We bail out to the runtime system to do that. | 2475 // global object. We bail out to the runtime system to do that. |
2470 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); | 2476 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); |
2471 __ CompareRoot(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 2477 __ CompareRoot(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), |
2472 Heap::kTheHoleValueRootIndex); | 2478 Heap::kTheHoleValueRootIndex); |
2473 __ j(equal, &miss); | 2479 __ j(equal, &miss); |
2474 | 2480 |
2475 // Store the value in the cell. | 2481 // Store the value in the cell. |
2476 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rax); | 2482 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rax); |
2477 | 2483 |
2478 // Return the value (register rax). | 2484 // Return the value (register rax). |
2479 __ IncrementCounter(&Counters::named_store_global_inline, 1); | 2485 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1); |
2480 __ ret(0); | 2486 __ ret(0); |
2481 | 2487 |
2482 // Handle store cache miss. | 2488 // Handle store cache miss. |
2483 __ bind(&miss); | 2489 __ bind(&miss); |
2484 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); | 2490 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1); |
2485 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2491 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2492 Builtins::StoreIC_Miss)); |
2486 __ Jump(ic, RelocInfo::CODE_TARGET); | 2493 __ Jump(ic, RelocInfo::CODE_TARGET); |
2487 | 2494 |
2488 // Return the generated code. | 2495 // Return the generated code. |
2489 return GetCode(NORMAL, name); | 2496 return GetCode(NORMAL, name); |
2490 } | 2497 } |
2491 | 2498 |
2492 | 2499 |
2493 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2500 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
2494 int index, | 2501 int index, |
2495 Map* transition, | 2502 Map* transition, |
2496 String* name) { | 2503 String* name) { |
2497 // ----------- S t a t e ------------- | 2504 // ----------- S t a t e ------------- |
2498 // -- rax : value | 2505 // -- rax : value |
2499 // -- rcx : key | 2506 // -- rcx : key |
2500 // -- rdx : receiver | 2507 // -- rdx : receiver |
2501 // -- rsp[0] : return address | 2508 // -- rsp[0] : return address |
2502 // ----------------------------------- | 2509 // ----------------------------------- |
2503 Label miss; | 2510 Label miss; |
2504 | 2511 |
2505 __ IncrementCounter(&Counters::keyed_store_field, 1); | 2512 __ IncrementCounter(COUNTERS->keyed_store_field(), 1); |
2506 | 2513 |
2507 // Check that the name has not changed. | 2514 // Check that the name has not changed. |
2508 __ Cmp(rcx, Handle<String>(name)); | 2515 __ Cmp(rcx, Handle<String>(name)); |
2509 __ j(not_equal, &miss); | 2516 __ j(not_equal, &miss); |
2510 | 2517 |
2511 // Generate store field code. Preserves receiver and name on jump to miss. | 2518 // Generate store field code. Preserves receiver and name on jump to miss. |
2512 GenerateStoreField(masm(), | 2519 GenerateStoreField(masm(), |
2513 object, | 2520 object, |
2514 index, | 2521 index, |
2515 transition, | 2522 transition, |
2516 rdx, rcx, rbx, | 2523 rdx, rcx, rbx, |
2517 &miss); | 2524 &miss); |
2518 | 2525 |
2519 // Handle store cache miss. | 2526 // Handle store cache miss. |
2520 __ bind(&miss); | 2527 __ bind(&miss); |
2521 __ DecrementCounter(&Counters::keyed_store_field, 1); | 2528 __ DecrementCounter(COUNTERS->keyed_store_field(), 1); |
2522 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 2529 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2530 Builtins::KeyedStoreIC_Miss)); |
2523 __ Jump(ic, RelocInfo::CODE_TARGET); | 2531 __ Jump(ic, RelocInfo::CODE_TARGET); |
2524 | 2532 |
2525 // Return the generated code. | 2533 // Return the generated code. |
2526 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2534 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2527 } | 2535 } |
2528 | 2536 |
2529 | 2537 |
2530 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( | 2538 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( |
2531 JSObject* receiver) { | 2539 JSObject* receiver) { |
2532 // ----------- S t a t e ------------- | 2540 // ----------- S t a t e ------------- |
(...skipping 11 matching lines...) Expand all Loading... |
2544 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 2552 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
2545 Handle<Map>(receiver->map())); | 2553 Handle<Map>(receiver->map())); |
2546 __ j(not_equal, &miss); | 2554 __ j(not_equal, &miss); |
2547 | 2555 |
2548 // Check that the key is a smi. | 2556 // Check that the key is a smi. |
2549 __ JumpIfNotSmi(rcx, &miss); | 2557 __ JumpIfNotSmi(rcx, &miss); |
2550 | 2558 |
2551 // Get the elements array and make sure it is a fast element array, not 'cow'. | 2559 // Get the elements array and make sure it is a fast element array, not 'cow'. |
2552 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 2560 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
2553 __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset), | 2561 __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset), |
2554 Factory::fixed_array_map()); | 2562 FACTORY->fixed_array_map()); |
2555 __ j(not_equal, &miss); | 2563 __ j(not_equal, &miss); |
2556 | 2564 |
2557 // Check that the key is within bounds. | 2565 // Check that the key is within bounds. |
2558 if (receiver->IsJSArray()) { | 2566 if (receiver->IsJSArray()) { |
2559 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 2567 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
2560 __ j(above_equal, &miss); | 2568 __ j(above_equal, &miss); |
2561 } else { | 2569 } else { |
2562 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); | 2570 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); |
2563 __ j(above_equal, &miss); | 2571 __ j(above_equal, &miss); |
2564 } | 2572 } |
2565 | 2573 |
2566 // Do the store and update the write barrier. Make sure to preserve | 2574 // Do the store and update the write barrier. Make sure to preserve |
2567 // the value in register eax. | 2575 // the value in register eax. |
2568 __ movq(rdx, rax); | 2576 __ movq(rdx, rax); |
2569 __ SmiToInteger32(rcx, rcx); | 2577 __ SmiToInteger32(rcx, rcx); |
2570 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), | 2578 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), |
2571 rax); | 2579 rax); |
2572 __ RecordWrite(rdi, 0, rdx, rcx); | 2580 __ RecordWrite(rdi, 0, rdx, rcx); |
2573 | 2581 |
2574 // Done. | 2582 // Done. |
2575 __ ret(0); | 2583 __ ret(0); |
2576 | 2584 |
2577 // Handle store cache miss. | 2585 // Handle store cache miss. |
2578 __ bind(&miss); | 2586 __ bind(&miss); |
2579 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 2587 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2588 Builtins::KeyedStoreIC_Miss)); |
2580 __ jmp(ic, RelocInfo::CODE_TARGET); | 2589 __ jmp(ic, RelocInfo::CODE_TARGET); |
2581 | 2590 |
2582 // Return the generated code. | 2591 // Return the generated code. |
2583 return GetCode(NORMAL, NULL); | 2592 return GetCode(NORMAL, NULL); |
2584 } | 2593 } |
2585 | 2594 |
2586 | 2595 |
2587 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2596 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
2588 JSObject* object, | 2597 JSObject* object, |
2589 JSObject* last) { | 2598 JSObject* last) { |
(...skipping 28 matching lines...) Expand all Loading... |
2618 | 2627 |
2619 // Return undefined if maps of the full prototype chain are still the | 2628 // Return undefined if maps of the full prototype chain are still the |
2620 // same and no global property with this name contains a value. | 2629 // same and no global property with this name contains a value. |
2621 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 2630 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
2622 __ ret(0); | 2631 __ ret(0); |
2623 | 2632 |
2624 __ bind(&miss); | 2633 __ bind(&miss); |
2625 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2634 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2626 | 2635 |
2627 // Return the generated code. | 2636 // Return the generated code. |
2628 return GetCode(NONEXISTENT, Heap::empty_string()); | 2637 return GetCode(NONEXISTENT, HEAP->empty_string()); |
2629 } | 2638 } |
2630 | 2639 |
2631 | 2640 |
2632 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 2641 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, |
2633 JSObject* holder, | 2642 JSObject* holder, |
2634 int index, | 2643 int index, |
2635 String* name) { | 2644 String* name) { |
2636 // ----------- S t a t e ------------- | 2645 // ----------- S t a t e ------------- |
2637 // -- rax : receiver | 2646 // -- rax : receiver |
2638 // -- rcx : name | 2647 // -- rcx : name |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2757 | 2766 |
2758 // Check for deleted property if property can actually be deleted. | 2767 // Check for deleted property if property can actually be deleted. |
2759 if (!is_dont_delete) { | 2768 if (!is_dont_delete) { |
2760 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 2769 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
2761 __ j(equal, &miss); | 2770 __ j(equal, &miss); |
2762 } else if (FLAG_debug_code) { | 2771 } else if (FLAG_debug_code) { |
2763 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 2772 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
2764 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 2773 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
2765 } | 2774 } |
2766 | 2775 |
2767 __ IncrementCounter(&Counters::named_load_global_stub, 1); | 2776 __ IncrementCounter(COUNTERS->named_load_global_stub(), 1); |
2768 __ movq(rax, rbx); | 2777 __ movq(rax, rbx); |
2769 __ ret(0); | 2778 __ ret(0); |
2770 | 2779 |
2771 __ bind(&miss); | 2780 __ bind(&miss); |
2772 __ IncrementCounter(&Counters::named_load_global_stub_miss, 1); | 2781 __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1); |
2773 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2782 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2774 | 2783 |
2775 // Return the generated code. | 2784 // Return the generated code. |
2776 return GetCode(NORMAL, name); | 2785 return GetCode(NORMAL, name); |
2777 } | 2786 } |
2778 | 2787 |
2779 | 2788 |
2780 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 2789 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, |
2781 JSObject* receiver, | 2790 JSObject* receiver, |
2782 JSObject* holder, | 2791 JSObject* holder, |
2783 int index) { | 2792 int index) { |
2784 // ----------- S t a t e ------------- | 2793 // ----------- S t a t e ------------- |
2785 // -- rax : key | 2794 // -- rax : key |
2786 // -- rdx : receiver | 2795 // -- rdx : receiver |
2787 // -- rsp[0] : return address | 2796 // -- rsp[0] : return address |
2788 // ----------------------------------- | 2797 // ----------------------------------- |
2789 Label miss; | 2798 Label miss; |
2790 | 2799 |
2791 __ IncrementCounter(&Counters::keyed_load_field, 1); | 2800 __ IncrementCounter(COUNTERS->keyed_load_field(), 1); |
2792 | 2801 |
2793 // Check that the name has not changed. | 2802 // Check that the name has not changed. |
2794 __ Cmp(rax, Handle<String>(name)); | 2803 __ Cmp(rax, Handle<String>(name)); |
2795 __ j(not_equal, &miss); | 2804 __ j(not_equal, &miss); |
2796 | 2805 |
2797 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); | 2806 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); |
2798 | 2807 |
2799 __ bind(&miss); | 2808 __ bind(&miss); |
2800 __ DecrementCounter(&Counters::keyed_load_field, 1); | 2809 __ DecrementCounter(COUNTERS->keyed_load_field(), 1); |
2801 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2810 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2802 | 2811 |
2803 // Return the generated code. | 2812 // Return the generated code. |
2804 return GetCode(FIELD, name); | 2813 return GetCode(FIELD, name); |
2805 } | 2814 } |
2806 | 2815 |
2807 | 2816 |
2808 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 2817 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( |
2809 String* name, | 2818 String* name, |
2810 JSObject* receiver, | 2819 JSObject* receiver, |
2811 JSObject* holder, | 2820 JSObject* holder, |
2812 AccessorInfo* callback) { | 2821 AccessorInfo* callback) { |
2813 // ----------- S t a t e ------------- | 2822 // ----------- S t a t e ------------- |
2814 // -- rax : key | 2823 // -- rax : key |
2815 // -- rdx : receiver | 2824 // -- rdx : receiver |
2816 // -- rsp[0] : return address | 2825 // -- rsp[0] : return address |
2817 // ----------------------------------- | 2826 // ----------------------------------- |
2818 Label miss; | 2827 Label miss; |
2819 | 2828 |
2820 __ IncrementCounter(&Counters::keyed_load_callback, 1); | 2829 __ IncrementCounter(COUNTERS->keyed_load_callback(), 1); |
2821 | 2830 |
2822 // Check that the name has not changed. | 2831 // Check that the name has not changed. |
2823 __ Cmp(rax, Handle<String>(name)); | 2832 __ Cmp(rax, Handle<String>(name)); |
2824 __ j(not_equal, &miss); | 2833 __ j(not_equal, &miss); |
2825 | 2834 |
2826 MaybeObject* result = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, | 2835 MaybeObject* result = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, |
2827 rcx, rdi, callback, name, &miss); | 2836 rcx, rdi, callback, name, &miss); |
2828 if (result->IsFailure()) { | 2837 if (result->IsFailure()) { |
2829 miss.Unuse(); | 2838 miss.Unuse(); |
2830 return result; | 2839 return result; |
2831 } | 2840 } |
2832 | 2841 |
2833 __ bind(&miss); | 2842 __ bind(&miss); |
2834 | 2843 |
2835 __ DecrementCounter(&Counters::keyed_load_callback, 1); | 2844 __ DecrementCounter(COUNTERS->keyed_load_callback(), 1); |
2836 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2845 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2837 | 2846 |
2838 // Return the generated code. | 2847 // Return the generated code. |
2839 return GetCode(CALLBACKS, name); | 2848 return GetCode(CALLBACKS, name); |
2840 } | 2849 } |
2841 | 2850 |
2842 | 2851 |
2843 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 2852 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
2844 JSObject* receiver, | 2853 JSObject* receiver, |
2845 JSObject* holder, | 2854 JSObject* holder, |
2846 Object* value) { | 2855 Object* value) { |
2847 // ----------- S t a t e ------------- | 2856 // ----------- S t a t e ------------- |
2848 // -- rax : key | 2857 // -- rax : key |
2849 // -- rdx : receiver | 2858 // -- rdx : receiver |
2850 // -- rsp[0] : return address | 2859 // -- rsp[0] : return address |
2851 // ----------------------------------- | 2860 // ----------------------------------- |
2852 Label miss; | 2861 Label miss; |
2853 | 2862 |
2854 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); | 2863 __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1); |
2855 | 2864 |
2856 // Check that the name has not changed. | 2865 // Check that the name has not changed. |
2857 __ Cmp(rax, Handle<String>(name)); | 2866 __ Cmp(rax, Handle<String>(name)); |
2858 __ j(not_equal, &miss); | 2867 __ j(not_equal, &miss); |
2859 | 2868 |
2860 GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi, | 2869 GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi, |
2861 value, name, &miss); | 2870 value, name, &miss); |
2862 __ bind(&miss); | 2871 __ bind(&miss); |
2863 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); | 2872 __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1); |
2864 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2873 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2865 | 2874 |
2866 // Return the generated code. | 2875 // Return the generated code. |
2867 return GetCode(CONSTANT_FUNCTION, name); | 2876 return GetCode(CONSTANT_FUNCTION, name); |
2868 } | 2877 } |
2869 | 2878 |
2870 | 2879 |
2871 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 2880 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
2872 JSObject* holder, | 2881 JSObject* holder, |
2873 String* name) { | 2882 String* name) { |
2874 // ----------- S t a t e ------------- | 2883 // ----------- S t a t e ------------- |
2875 // -- rax : key | 2884 // -- rax : key |
2876 // -- rdx : receiver | 2885 // -- rdx : receiver |
2877 // -- rsp[0] : return address | 2886 // -- rsp[0] : return address |
2878 // ----------------------------------- | 2887 // ----------------------------------- |
2879 Label miss; | 2888 Label miss; |
2880 | 2889 |
2881 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); | 2890 __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1); |
2882 | 2891 |
2883 // Check that the name has not changed. | 2892 // Check that the name has not changed. |
2884 __ Cmp(rax, Handle<String>(name)); | 2893 __ Cmp(rax, Handle<String>(name)); |
2885 __ j(not_equal, &miss); | 2894 __ j(not_equal, &miss); |
2886 | 2895 |
2887 LookupResult lookup; | 2896 LookupResult lookup; |
2888 LookupPostInterceptor(holder, name, &lookup); | 2897 LookupPostInterceptor(holder, name, &lookup); |
2889 GenerateLoadInterceptor(receiver, | 2898 GenerateLoadInterceptor(receiver, |
2890 holder, | 2899 holder, |
2891 &lookup, | 2900 &lookup, |
2892 rdx, | 2901 rdx, |
2893 rax, | 2902 rax, |
2894 rcx, | 2903 rcx, |
2895 rbx, | 2904 rbx, |
2896 rdi, | 2905 rdi, |
2897 name, | 2906 name, |
2898 &miss); | 2907 &miss); |
2899 __ bind(&miss); | 2908 __ bind(&miss); |
2900 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 2909 __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1); |
2901 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2910 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2902 | 2911 |
2903 // Return the generated code. | 2912 // Return the generated code. |
2904 return GetCode(INTERCEPTOR, name); | 2913 return GetCode(INTERCEPTOR, name); |
2905 } | 2914 } |
2906 | 2915 |
2907 | 2916 |
2908 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 2917 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
2909 // ----------- S t a t e ------------- | 2918 // ----------- S t a t e ------------- |
2910 // -- rax : key | 2919 // -- rax : key |
2911 // -- rdx : receiver | 2920 // -- rdx : receiver |
2912 // -- rsp[0] : return address | 2921 // -- rsp[0] : return address |
2913 // ----------------------------------- | 2922 // ----------------------------------- |
2914 Label miss; | 2923 Label miss; |
2915 | 2924 |
2916 __ IncrementCounter(&Counters::keyed_load_array_length, 1); | 2925 __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1); |
2917 | 2926 |
2918 // Check that the name has not changed. | 2927 // Check that the name has not changed. |
2919 __ Cmp(rax, Handle<String>(name)); | 2928 __ Cmp(rax, Handle<String>(name)); |
2920 __ j(not_equal, &miss); | 2929 __ j(not_equal, &miss); |
2921 | 2930 |
2922 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); | 2931 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); |
2923 __ bind(&miss); | 2932 __ bind(&miss); |
2924 __ DecrementCounter(&Counters::keyed_load_array_length, 1); | 2933 __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1); |
2925 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2934 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2926 | 2935 |
2927 // Return the generated code. | 2936 // Return the generated code. |
2928 return GetCode(CALLBACKS, name); | 2937 return GetCode(CALLBACKS, name); |
2929 } | 2938 } |
2930 | 2939 |
2931 | 2940 |
2932 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 2941 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
2933 // ----------- S t a t e ------------- | 2942 // ----------- S t a t e ------------- |
2934 // -- rax : key | 2943 // -- rax : key |
2935 // -- rdx : receiver | 2944 // -- rdx : receiver |
2936 // -- rsp[0] : return address | 2945 // -- rsp[0] : return address |
2937 // ----------------------------------- | 2946 // ----------------------------------- |
2938 Label miss; | 2947 Label miss; |
2939 | 2948 |
2940 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 2949 __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1); |
2941 | 2950 |
2942 // Check that the name has not changed. | 2951 // Check that the name has not changed. |
2943 __ Cmp(rax, Handle<String>(name)); | 2952 __ Cmp(rax, Handle<String>(name)); |
2944 __ j(not_equal, &miss); | 2953 __ j(not_equal, &miss); |
2945 | 2954 |
2946 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); | 2955 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); |
2947 __ bind(&miss); | 2956 __ bind(&miss); |
2948 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 2957 __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1); |
2949 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2958 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2950 | 2959 |
2951 // Return the generated code. | 2960 // Return the generated code. |
2952 return GetCode(CALLBACKS, name); | 2961 return GetCode(CALLBACKS, name); |
2953 } | 2962 } |
2954 | 2963 |
2955 | 2964 |
2956 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 2965 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
2957 // ----------- S t a t e ------------- | 2966 // ----------- S t a t e ------------- |
2958 // -- rax : key | 2967 // -- rax : key |
2959 // -- rdx : receiver | 2968 // -- rdx : receiver |
2960 // -- rsp[0] : return address | 2969 // -- rsp[0] : return address |
2961 // ----------------------------------- | 2970 // ----------------------------------- |
2962 Label miss; | 2971 Label miss; |
2963 | 2972 |
2964 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); | 2973 __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1); |
2965 | 2974 |
2966 // Check that the name has not changed. | 2975 // Check that the name has not changed. |
2967 __ Cmp(rax, Handle<String>(name)); | 2976 __ Cmp(rax, Handle<String>(name)); |
2968 __ j(not_equal, &miss); | 2977 __ j(not_equal, &miss); |
2969 | 2978 |
2970 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); | 2979 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); |
2971 __ bind(&miss); | 2980 __ bind(&miss); |
2972 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); | 2981 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1); |
2973 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2982 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2974 | 2983 |
2975 // Return the generated code. | 2984 // Return the generated code. |
2976 return GetCode(CALLBACKS, name); | 2985 return GetCode(CALLBACKS, name); |
2977 } | 2986 } |
2978 | 2987 |
2979 | 2988 |
2980 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { | 2989 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { |
2981 // ----------- S t a t e ------------- | 2990 // ----------- S t a t e ------------- |
2982 // -- rax : key | 2991 // -- rax : key |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3028 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3037 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
3029 // ----------- S t a t e ------------- | 3038 // ----------- S t a t e ------------- |
3030 // -- rax : argc | 3039 // -- rax : argc |
3031 // -- rdi : constructor | 3040 // -- rdi : constructor |
3032 // -- rsp[0] : return address | 3041 // -- rsp[0] : return address |
3033 // -- rsp[4] : last argument | 3042 // -- rsp[4] : last argument |
3034 // ----------------------------------- | 3043 // ----------------------------------- |
3035 Label generic_stub_call; | 3044 Label generic_stub_call; |
3036 | 3045 |
3037 // Use r8 for holding undefined which is used in several places below. | 3046 // Use r8 for holding undefined which is used in several places below. |
3038 __ Move(r8, Factory::undefined_value()); | 3047 __ Move(r8, FACTORY->undefined_value()); |
3039 | 3048 |
3040 #ifdef ENABLE_DEBUGGER_SUPPORT | 3049 #ifdef ENABLE_DEBUGGER_SUPPORT |
3041 // Check to see whether there are any break points in the function code. If | 3050 // Check to see whether there are any break points in the function code. If |
3042 // there are jump to the generic constructor stub which calls the actual | 3051 // there are jump to the generic constructor stub which calls the actual |
3043 // code for the function thereby hitting the break points. | 3052 // code for the function thereby hitting the break points. |
3044 __ movq(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 3053 __ movq(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
3045 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kDebugInfoOffset)); | 3054 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kDebugInfoOffset)); |
3046 __ cmpq(rbx, r8); | 3055 __ cmpq(rbx, r8); |
3047 __ j(not_equal, &generic_stub_call); | 3056 __ j(not_equal, &generic_stub_call); |
3048 #endif | 3057 #endif |
(...skipping 23 matching lines...) Expand all Loading... |
3072 rdx, | 3081 rdx, |
3073 rcx, | 3082 rcx, |
3074 no_reg, | 3083 no_reg, |
3075 &generic_stub_call, | 3084 &generic_stub_call, |
3076 NO_ALLOCATION_FLAGS); | 3085 NO_ALLOCATION_FLAGS); |
3077 | 3086 |
3078 // Allocated the JSObject, now initialize the fields and add the heap tag. | 3087 // Allocated the JSObject, now initialize the fields and add the heap tag. |
3079 // rbx: initial map | 3088 // rbx: initial map |
3080 // rdx: JSObject (untagged) | 3089 // rdx: JSObject (untagged) |
3081 __ movq(Operand(rdx, JSObject::kMapOffset), rbx); | 3090 __ movq(Operand(rdx, JSObject::kMapOffset), rbx); |
3082 __ Move(rbx, Factory::empty_fixed_array()); | 3091 __ Move(rbx, FACTORY->empty_fixed_array()); |
3083 __ movq(Operand(rdx, JSObject::kPropertiesOffset), rbx); | 3092 __ movq(Operand(rdx, JSObject::kPropertiesOffset), rbx); |
3084 __ movq(Operand(rdx, JSObject::kElementsOffset), rbx); | 3093 __ movq(Operand(rdx, JSObject::kElementsOffset), rbx); |
3085 | 3094 |
3086 // rax: argc | 3095 // rax: argc |
3087 // rdx: JSObject (untagged) | 3096 // rdx: JSObject (untagged) |
3088 // Load the address of the first in-object property into r9. | 3097 // Load the address of the first in-object property into r9. |
3089 __ lea(r9, Operand(rdx, JSObject::kHeaderSize)); | 3098 __ lea(r9, Operand(rdx, JSObject::kHeaderSize)); |
3090 // Calculate the location of the first argument. The stack contains only the | 3099 // Calculate the location of the first argument. The stack contains only the |
3091 // return address on top of the argc arguments. | 3100 // return address on top of the argc arguments. |
3092 __ lea(rcx, Operand(rsp, rax, times_pointer_size, 0)); | 3101 __ lea(rcx, Operand(rsp, rax, times_pointer_size, 0)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 __ movq(rbx, rax); | 3140 __ movq(rbx, rax); |
3132 __ movq(rax, rdx); | 3141 __ movq(rax, rdx); |
3133 __ or_(rax, Immediate(kHeapObjectTag)); | 3142 __ or_(rax, Immediate(kHeapObjectTag)); |
3134 | 3143 |
3135 // rax: JSObject | 3144 // rax: JSObject |
3136 // rbx: argc | 3145 // rbx: argc |
3137 // Remove caller arguments and receiver from the stack and return. | 3146 // Remove caller arguments and receiver from the stack and return. |
3138 __ pop(rcx); | 3147 __ pop(rcx); |
3139 __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize)); | 3148 __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize)); |
3140 __ push(rcx); | 3149 __ push(rcx); |
3141 __ IncrementCounter(&Counters::constructed_objects, 1); | 3150 __ IncrementCounter(COUNTERS->constructed_objects(), 1); |
3142 __ IncrementCounter(&Counters::constructed_objects_stub, 1); | 3151 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1); |
3143 __ ret(0); | 3152 __ ret(0); |
3144 | 3153 |
3145 // Jump to the generic stub in case the specialized code cannot handle the | 3154 // Jump to the generic stub in case the specialized code cannot handle the |
3146 // construction. | 3155 // construction. |
3147 __ bind(&generic_stub_call); | 3156 __ bind(&generic_stub_call); |
3148 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); | 3157 Code* code = Isolate::Current()->builtins()->builtin( |
| 3158 Builtins::JSConstructStubGeneric); |
3149 Handle<Code> generic_construct_stub(code); | 3159 Handle<Code> generic_construct_stub(code); |
3150 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 3160 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
3151 | 3161 |
3152 // Return the generated code. | 3162 // Return the generated code. |
3153 return GetCode(); | 3163 return GetCode(); |
3154 } | 3164 } |
3155 | 3165 |
3156 | 3166 |
3157 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( | 3167 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
3158 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { | 3168 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3253 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); | 3263 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); |
3254 __ movq(rax, rcx); | 3264 __ movq(rax, rcx); |
3255 __ ret(0); | 3265 __ ret(0); |
3256 } else { | 3266 } else { |
3257 __ Integer32ToSmi(rax, rcx); | 3267 __ Integer32ToSmi(rax, rcx); |
3258 __ ret(0); | 3268 __ ret(0); |
3259 } | 3269 } |
3260 | 3270 |
3261 // Slow case: Jump to runtime. | 3271 // Slow case: Jump to runtime. |
3262 __ bind(&slow); | 3272 __ bind(&slow); |
3263 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); | 3273 __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1); |
3264 | 3274 |
3265 // ----------- S t a t e ------------- | 3275 // ----------- S t a t e ------------- |
3266 // -- rax : key | 3276 // -- rax : key |
3267 // -- rdx : receiver | 3277 // -- rdx : receiver |
3268 // -- rsp[0] : return address | 3278 // -- rsp[0] : return address |
3269 // ----------------------------------- | 3279 // ----------------------------------- |
3270 | 3280 |
3271 __ pop(rbx); | 3281 __ pop(rbx); |
3272 __ push(rdx); // receiver | 3282 __ push(rdx); // receiver |
3273 __ push(rax); // name | 3283 __ push(rax); // name |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3444 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 3454 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
3445 | 3455 |
3446 return GetCode(flags); | 3456 return GetCode(flags); |
3447 } | 3457 } |
3448 | 3458 |
3449 #undef __ | 3459 #undef __ |
3450 | 3460 |
3451 } } // namespace v8::internal | 3461 } } // namespace v8::internal |
3452 | 3462 |
3453 #endif // V8_TARGET_ARCH_X64 | 3463 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |