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

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

Issue 6880010: Merge (7265, 7271] from bleeding_edge to experimental/gc branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 21 matching lines...) Expand all
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 Register extra) { 48 Register extra) {
48 ExternalReference key_offset(SCTableReference::keyReference(table)); 49 ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
49 ExternalReference value_offset(SCTableReference::valueReference(table)); 50 ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
50 51
51 Label miss; 52 Label miss;
52 53
53 if (extra.is_valid()) { 54 if (extra.is_valid()) {
54 // Get the code entry from the cache. 55 // Get the code entry from the cache.
55 __ mov(extra, Operand::StaticArray(offset, times_2, value_offset)); 56 __ mov(extra, Operand::StaticArray(offset, times_2, value_offset));
56 57
57 // Check that the key in the entry matches the name. 58 // Check that the key in the entry matches the name.
58 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset)); 59 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));
59 __ j(not_equal, &miss, not_taken); 60 __ j(not_equal, &miss, not_taken);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // must always call a backup property check that is complete. 107 // must always call a backup property check that is complete.
107 // This function is safe to call if the receiver has fast properties. 108 // This function is safe to call if the receiver has fast properties.
108 // Name must be a symbol and receiver must be a heap object. 109 // Name must be a symbol and receiver must be a heap object.
109 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, 110 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
110 Label* miss_label, 111 Label* miss_label,
111 Register receiver, 112 Register receiver,
112 String* name, 113 String* name,
113 Register r0, 114 Register r0,
114 Register r1) { 115 Register r1) {
115 ASSERT(name->IsSymbol()); 116 ASSERT(name->IsSymbol());
116 __ IncrementCounter(&Counters::negative_lookups, 1); 117 __ IncrementCounter(COUNTERS->negative_lookups(), 1);
117 __ IncrementCounter(&Counters::negative_lookups_miss, 1); 118 __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1);
118 119
119 Label done; 120 Label done;
120 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); 121 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
121 122
122 const int kInterceptorOrAccessCheckNeededMask = 123 const int kInterceptorOrAccessCheckNeededMask =
123 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
124 125
125 // Bail out if the receiver has a named interceptor or requires access checks. 126 // Bail out if the receiver has a named interceptor or requires access checks.
126 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), 127 __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
127 kInterceptorOrAccessCheckNeededMask); 128 kInterceptorOrAccessCheckNeededMask);
128 __ j(not_zero, miss_label, not_taken); 129 __ j(not_zero, miss_label, not_taken);
129 130
130 // Check that receiver is a JSObject. 131 // Check that receiver is a JSObject.
131 __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE); 132 __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE);
132 __ j(below, miss_label, not_taken); 133 __ j(below, miss_label, not_taken);
133 134
134 // Load properties array. 135 // Load properties array.
135 Register properties = r0; 136 Register properties = r0;
136 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 137 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
137 138
138 // Check that the properties array is a dictionary. 139 // Check that the properties array is a dictionary.
139 __ cmp(FieldOperand(properties, HeapObject::kMapOffset), 140 __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
140 Immediate(Factory::hash_table_map())); 141 Immediate(FACTORY->hash_table_map()));
141 __ j(not_equal, miss_label); 142 __ j(not_equal, miss_label);
142 143
143 // Compute the capacity mask. 144 // Compute the capacity mask.
144 const int kCapacityOffset = 145 const int kCapacityOffset =
145 StringDictionary::kHeaderSize + 146 StringDictionary::kHeaderSize +
146 StringDictionary::kCapacityIndex * kPointerSize; 147 StringDictionary::kCapacityIndex * kPointerSize;
147 148
148 // Generate an unrolled loop that performs a few probes before 149 // Generate an unrolled loop that performs a few probes before
149 // giving up. 150 // giving up.
150 static const int kProbes = 4; 151 static const int kProbes = 4;
(...skipping 19 matching lines...) Expand all
170 171
171 // Scale the index by multiplying by the entry size. 172 // Scale the index by multiplying by the entry size.
172 ASSERT(StringDictionary::kEntrySize == 3); 173 ASSERT(StringDictionary::kEntrySize == 3);
173 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. 174 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3.
174 175
175 Register entity_name = r1; 176 Register entity_name = r1;
176 // Having undefined at this place means the name is not contained. 177 // Having undefined at this place means the name is not contained.
177 ASSERT_EQ(kSmiTagSize, 1); 178 ASSERT_EQ(kSmiTagSize, 1);
178 __ mov(entity_name, Operand(properties, index, times_half_pointer_size, 179 __ mov(entity_name, Operand(properties, index, times_half_pointer_size,
179 kElementsStartOffset - kHeapObjectTag)); 180 kElementsStartOffset - kHeapObjectTag));
180 __ cmp(entity_name, Factory::undefined_value()); 181 __ cmp(entity_name, FACTORY->undefined_value());
181 if (i != kProbes - 1) { 182 if (i != kProbes - 1) {
182 __ j(equal, &done, taken); 183 __ j(equal, &done, taken);
183 184
184 // Stop if found the property. 185 // Stop if found the property.
185 __ cmp(entity_name, Handle<String>(name)); 186 __ cmp(entity_name, Handle<String>(name));
186 __ j(equal, miss_label, not_taken); 187 __ j(equal, miss_label, not_taken);
187 188
188 // Check if the entry name is not a symbol. 189 // Check if the entry name is not a symbol.
189 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 190 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
190 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), 191 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset),
191 kIsSymbolMask); 192 kIsSymbolMask);
192 __ j(zero, miss_label, not_taken); 193 __ j(zero, miss_label, not_taken);
193 } else { 194 } else {
194 // Give up probing if still not found the undefined value. 195 // Give up probing if still not found the undefined value.
195 __ j(not_equal, miss_label, not_taken); 196 __ j(not_equal, miss_label, not_taken);
196 } 197 }
197 } 198 }
198 199
199 __ bind(&done); 200 __ bind(&done);
200 __ DecrementCounter(&Counters::negative_lookups_miss, 1); 201 __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1);
201 } 202 }
202 203
203 204
204 void StubCache::GenerateProbe(MacroAssembler* masm, 205 void StubCache::GenerateProbe(MacroAssembler* masm,
205 Code::Flags flags, 206 Code::Flags flags,
206 Register receiver, 207 Register receiver,
207 Register name, 208 Register name,
208 Register scratch, 209 Register scratch,
209 Register extra, 210 Register extra,
210 Register extra2) { 211 Register extra2) {
212 Isolate* isolate = Isolate::Current();
211 Label miss; 213 Label miss;
212 USE(extra2); // The register extra2 is not used on the ia32 platform. 214 USE(extra2); // The register extra2 is not used on the ia32 platform.
213 215
214 // Make sure that code is valid. The shifting code relies on the 216 // Make sure that code is valid. The shifting code relies on the
215 // entry size being 8. 217 // entry size being 8.
216 ASSERT(sizeof(Entry) == 8); 218 ASSERT(sizeof(Entry) == 8);
217 219
218 // Make sure the flags does not name a specific type. 220 // Make sure the flags does not name a specific type.
219 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 221 ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
220 222
(...skipping 12 matching lines...) Expand all
233 __ test(receiver, Immediate(kSmiTagMask)); 235 __ test(receiver, Immediate(kSmiTagMask));
234 __ j(zero, &miss, not_taken); 236 __ j(zero, &miss, not_taken);
235 237
236 // Get the map of the receiver and compute the hash. 238 // Get the map of the receiver and compute the hash.
237 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); 239 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
238 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 240 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
239 __ xor_(scratch, flags); 241 __ xor_(scratch, flags);
240 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 242 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
241 243
242 // Probe the primary table. 244 // Probe the primary table.
243 ProbeTable(masm, flags, kPrimary, name, scratch, extra); 245 ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra);
244 246
245 // Primary miss: Compute hash for secondary probe. 247 // Primary miss: Compute hash for secondary probe.
246 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); 248 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
247 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 249 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
248 __ xor_(scratch, flags); 250 __ xor_(scratch, flags);
249 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 251 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
250 __ sub(scratch, Operand(name)); 252 __ sub(scratch, Operand(name));
251 __ add(Operand(scratch), Immediate(flags)); 253 __ add(Operand(scratch), Immediate(flags));
252 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); 254 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);
253 255
254 // Probe the secondary table. 256 // Probe the secondary table.
255 ProbeTable(masm, flags, kSecondary, name, scratch, extra); 257 ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra);
256 258
257 // Cache miss: Fall-through and let caller handle the miss by 259 // Cache miss: Fall-through and let caller handle the miss by
258 // entering the runtime system. 260 // entering the runtime system.
259 __ bind(&miss); 261 __ bind(&miss);
260 } 262 }
261 263
262 264
263 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 265 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
264 int index, 266 int index,
265 Register prototype) { 267 Register prototype) {
266 __ LoadGlobalFunction(index, prototype); 268 __ LoadGlobalFunction(index, prototype);
267 __ LoadGlobalFunctionInitialMap(prototype, prototype); 269 __ LoadGlobalFunctionInitialMap(prototype, prototype);
268 // Load the prototype from the initial map. 270 // Load the prototype from the initial map.
269 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 271 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
270 } 272 }
271 273
272 274
273 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 275 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
274 MacroAssembler* masm, int index, Register prototype, Label* miss) { 276 MacroAssembler* masm, int index, Register prototype, Label* miss) {
275 // Check we're still in the same context. 277 // Check we're still in the same context.
276 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)), 278 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
277 Top::global()); 279 Isolate::Current()->global());
278 __ j(not_equal, miss); 280 __ j(not_equal, miss);
279 // Get the global function with the given index. 281 // Get the global function with the given index.
280 JSFunction* function = JSFunction::cast(Top::global_context()->get(index)); 282 JSFunction* function = JSFunction::cast(
283 Isolate::Current()->global_context()->get(index));
281 // Load its initial map. The global functions all have initial maps. 284 // Load its initial map. The global functions all have initial maps.
282 __ Set(prototype, Immediate(Handle<Map>(function->initial_map()))); 285 __ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
283 // Load the prototype from the initial map. 286 // Load the prototype from the initial map.
284 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 287 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
285 } 288 }
286 289
287 290
288 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 291 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
289 Register receiver, 292 Register receiver,
290 Register scratch, 293 Register scratch,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 } 391 }
389 392
390 393
391 static void PushInterceptorArguments(MacroAssembler* masm, 394 static void PushInterceptorArguments(MacroAssembler* masm,
392 Register receiver, 395 Register receiver,
393 Register holder, 396 Register holder,
394 Register name, 397 Register name,
395 JSObject* holder_obj) { 398 JSObject* holder_obj) {
396 __ push(name); 399 __ push(name);
397 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 400 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
398 ASSERT(!Heap::InNewSpace(interceptor)); 401 ASSERT(!HEAP->InNewSpace(interceptor));
399 Register scratch = name; 402 Register scratch = name;
400 __ mov(scratch, Immediate(Handle<Object>(interceptor))); 403 __ mov(scratch, Immediate(Handle<Object>(interceptor)));
401 __ push(scratch); 404 __ push(scratch);
402 __ push(receiver); 405 __ push(receiver);
403 __ push(holder); 406 __ push(holder);
404 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); 407 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset));
405 } 408 }
406 409
407 410
408 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 411 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 // ----------------------------------- 476 // -----------------------------------
474 // Get the function and setup the context. 477 // Get the function and setup the context.
475 JSFunction* function = optimization.constant_function(); 478 JSFunction* function = optimization.constant_function();
476 __ mov(edi, Immediate(Handle<JSFunction>(function))); 479 __ mov(edi, Immediate(Handle<JSFunction>(function)));
477 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 480 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
478 481
479 // Pass the additional arguments. 482 // Pass the additional arguments.
480 __ mov(Operand(esp, 2 * kPointerSize), edi); 483 __ mov(Operand(esp, 2 * kPointerSize), edi);
481 Object* call_data = optimization.api_call_info()->data(); 484 Object* call_data = optimization.api_call_info()->data();
482 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); 485 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
483 if (Heap::InNewSpace(call_data)) { 486 if (HEAP->InNewSpace(call_data)) {
484 __ mov(ecx, api_call_info_handle); 487 __ mov(ecx, api_call_info_handle);
485 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); 488 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
486 __ mov(Operand(esp, 3 * kPointerSize), ebx); 489 __ mov(Operand(esp, 3 * kPointerSize), ebx);
487 } else { 490 } else {
488 __ mov(Operand(esp, 3 * kPointerSize), 491 __ mov(Operand(esp, 3 * kPointerSize),
489 Immediate(Handle<Object>(call_data))); 492 Immediate(Handle<Object>(call_data)));
490 } 493 }
491 494
492 // Prepare arguments. 495 // Prepare arguments.
493 __ lea(eax, Operand(esp, 3 * kPointerSize)); 496 __ lea(eax, Operand(esp, 3 * kPointerSize));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 } else { 570 } else {
568 CompileRegular(masm, 571 CompileRegular(masm,
569 object, 572 object,
570 receiver, 573 receiver,
571 scratch1, 574 scratch1,
572 scratch2, 575 scratch2,
573 scratch3, 576 scratch3,
574 name, 577 name,
575 holder, 578 holder,
576 miss); 579 miss);
577 return Heap::undefined_value(); // Success. 580 return HEAP->undefined_value(); // Success.
578 } 581 }
579 } 582 }
580 583
581 private: 584 private:
582 MaybeObject* CompileCacheable(MacroAssembler* masm, 585 MaybeObject* CompileCacheable(MacroAssembler* masm,
583 JSObject* object, 586 JSObject* object,
584 Register receiver, 587 Register receiver,
585 Register scratch1, 588 Register scratch1,
586 Register scratch2, 589 Register scratch2,
587 Register scratch3, 590 Register scratch3,
(...skipping 15 matching lines...) Expand all
603 interceptor_holder); 606 interceptor_holder);
604 if (depth1 == kInvalidProtoDepth) { 607 if (depth1 == kInvalidProtoDepth) {
605 depth2 = 608 depth2 =
606 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, 609 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder,
607 lookup->holder()); 610 lookup->holder());
608 } 611 }
609 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || 612 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) ||
610 (depth2 != kInvalidProtoDepth); 613 (depth2 != kInvalidProtoDepth);
611 } 614 }
612 615
613 __ IncrementCounter(&Counters::call_const_interceptor, 1); 616 __ IncrementCounter(COUNTERS->call_const_interceptor(), 1);
614 617
615 if (can_do_fast_api_call) { 618 if (can_do_fast_api_call) {
616 __ IncrementCounter(&Counters::call_const_interceptor_fast_api, 1); 619 __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1);
617 ReserveSpaceForFastApiCall(masm, scratch1); 620 ReserveSpaceForFastApiCall(masm, scratch1);
618 } 621 }
619 622
620 // Check that the maps from receiver to interceptor's holder 623 // Check that the maps from receiver to interceptor's holder
621 // haven't changed and thus we can invoke interceptor. 624 // haven't changed and thus we can invoke interceptor.
622 Label miss_cleanup; 625 Label miss_cleanup;
623 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 626 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
624 Register holder = 627 Register holder =
625 stub_compiler_->CheckPrototypes(object, receiver, 628 stub_compiler_->CheckPrototypes(object, receiver,
626 interceptor_holder, scratch1, 629 interceptor_holder, scratch1,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 FreeSpaceForFastApiCall(masm, scratch1); 668 FreeSpaceForFastApiCall(masm, scratch1);
666 __ jmp(miss_label); 669 __ jmp(miss_label);
667 } 670 }
668 671
669 // Invoke a regular function. 672 // Invoke a regular function.
670 __ bind(&regular_invoke); 673 __ bind(&regular_invoke);
671 if (can_do_fast_api_call) { 674 if (can_do_fast_api_call) {
672 FreeSpaceForFastApiCall(masm, scratch1); 675 FreeSpaceForFastApiCall(masm, scratch1);
673 } 676 }
674 677
675 return Heap::undefined_value(); // Success. 678 return HEAP->undefined_value(); // Success.
676 } 679 }
677 680
678 void CompileRegular(MacroAssembler* masm, 681 void CompileRegular(MacroAssembler* masm,
679 JSObject* object, 682 JSObject* object,
680 Register receiver, 683 Register receiver,
681 Register scratch1, 684 Register scratch1,
682 Register scratch2, 685 Register scratch2,
683 Register scratch3, 686 Register scratch3,
684 String* name, 687 String* name,
685 JSObject* interceptor_holder, 688 JSObject* interceptor_holder,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 CompileCallLoadPropertyWithInterceptor(masm, 724 CompileCallLoadPropertyWithInterceptor(masm,
722 receiver, 725 receiver,
723 holder, 726 holder,
724 name_, 727 name_,
725 holder_obj); 728 holder_obj);
726 729
727 __ pop(name_); // Restore the name. 730 __ pop(name_); // Restore the name.
728 __ pop(receiver); // Restore the holder. 731 __ pop(receiver); // Restore the holder.
729 __ LeaveInternalFrame(); 732 __ LeaveInternalFrame();
730 733
731 __ cmp(eax, Factory::no_interceptor_result_sentinel()); 734 __ cmp(eax, FACTORY->no_interceptor_result_sentinel());
732 __ j(not_equal, interceptor_succeeded); 735 __ j(not_equal, interceptor_succeeded);
733 } 736 }
734 737
735 StubCompiler* stub_compiler_; 738 StubCompiler* stub_compiler_;
736 const ParameterCount& arguments_; 739 const ParameterCount& arguments_;
737 Register name_; 740 Register name_;
738 }; 741 };
739 742
740 743
741 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 744 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
742 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 745 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
743 Code* code = NULL; 746 Code* code = NULL;
744 if (kind == Code::LOAD_IC) { 747 if (kind == Code::LOAD_IC) {
745 code = Builtins::builtin(Builtins::LoadIC_Miss); 748 code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
746 } else { 749 } else {
747 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); 750 code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
748 } 751 }
749 752
750 Handle<Code> ic(code); 753 Handle<Code> ic(code);
751 __ jmp(ic, RelocInfo::CODE_TARGET); 754 __ jmp(ic, RelocInfo::CODE_TARGET);
752 } 755 }
753 756
754 757
755 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 758 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
756 // but may be destroyed if store is successful. 759 // but may be destroyed if store is successful.
757 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 760 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 Label* miss) { 847 Label* miss) {
845 Object* probe; 848 Object* probe;
846 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 849 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
847 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 850 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
848 } 851 }
849 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 852 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
850 ASSERT(cell->value()->IsTheHole()); 853 ASSERT(cell->value()->IsTheHole());
851 if (Serializer::enabled()) { 854 if (Serializer::enabled()) {
852 __ mov(scratch, Immediate(Handle<Object>(cell))); 855 __ mov(scratch, Immediate(Handle<Object>(cell)));
853 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), 856 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
854 Immediate(Factory::the_hole_value())); 857 Immediate(FACTORY->the_hole_value()));
855 } else { 858 } else {
856 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), 859 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)),
857 Immediate(Factory::the_hole_value())); 860 Immediate(FACTORY->the_hole_value()));
858 } 861 }
859 __ j(not_equal, miss, not_taken); 862 __ j(not_equal, miss, not_taken);
860 return cell; 863 return cell;
861 } 864 }
862 865
863 866
864 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 867 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
865 // from object to (but not including) holder. 868 // from object to (but not including) holder.
866 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( 869 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells(
867 MacroAssembler* masm, 870 MacroAssembler* masm,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 // Only global objects and objects that do not require access 926 // Only global objects and objects that do not require access
924 // checks are allowed in stubs. 927 // checks are allowed in stubs.
925 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 928 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
926 929
927 ASSERT(current->GetPrototype()->IsJSObject()); 930 ASSERT(current->GetPrototype()->IsJSObject());
928 JSObject* prototype = JSObject::cast(current->GetPrototype()); 931 JSObject* prototype = JSObject::cast(current->GetPrototype());
929 if (!current->HasFastProperties() && 932 if (!current->HasFastProperties() &&
930 !current->IsJSGlobalObject() && 933 !current->IsJSGlobalObject() &&
931 !current->IsJSGlobalProxy()) { 934 !current->IsJSGlobalProxy()) {
932 if (!name->IsSymbol()) { 935 if (!name->IsSymbol()) {
933 MaybeObject* maybe_lookup_result = Heap::LookupSymbol(name); 936 MaybeObject* maybe_lookup_result = HEAP->LookupSymbol(name);
934 Object* lookup_result = NULL; // Initialization to please compiler. 937 Object* lookup_result = NULL; // Initialization to please compiler.
935 if (!maybe_lookup_result->ToObject(&lookup_result)) { 938 if (!maybe_lookup_result->ToObject(&lookup_result)) {
936 set_failure(Failure::cast(maybe_lookup_result)); 939 set_failure(Failure::cast(maybe_lookup_result));
937 return reg; 940 return reg;
938 } 941 }
939 name = String::cast(lookup_result); 942 name = String::cast(lookup_result);
940 } 943 }
941 ASSERT(current->property_dictionary()->FindEntry(name) == 944 ASSERT(current->property_dictionary()->FindEntry(name) ==
942 StringDictionary::kNotFound); 945 StringDictionary::kNotFound);
943 946
944 GenerateDictionaryNegativeLookup(masm(), 947 GenerateDictionaryNegativeLookup(masm(),
945 miss, 948 miss,
946 reg, 949 reg,
947 name, 950 name,
948 scratch1, 951 scratch1,
949 scratch2); 952 scratch2);
950 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 953 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
951 reg = holder_reg; // from now the object is in holder_reg 954 reg = holder_reg; // from now the object is in holder_reg
952 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 955 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
953 } else if (Heap::InNewSpace(prototype)) { 956 } else if (HEAP->InNewSpace(prototype)) {
954 // Get the map of the current object. 957 // Get the map of the current object.
955 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 958 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
956 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); 959 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map())));
957 // Branch on the result of the map check. 960 // Branch on the result of the map check.
958 __ j(not_equal, miss, not_taken); 961 __ j(not_equal, miss, not_taken);
959 // Check access rights to the global object. This has to happen 962 // Check access rights to the global object. This has to happen
960 // after the map check so that we know that the object is 963 // after the map check so that we know that the object is
961 // actually a global object. 964 // actually a global object.
962 if (current->IsJSGlobalProxy()) { 965 if (current->IsJSGlobalProxy()) {
963 __ CheckAccessGlobalProxy(reg, scratch1, miss); 966 __ CheckAccessGlobalProxy(reg, scratch1, miss);
(...skipping 26 matching lines...) Expand all
990 if (save_at_depth == depth) { 993 if (save_at_depth == depth) {
991 __ mov(Operand(esp, kPointerSize), reg); 994 __ mov(Operand(esp, kPointerSize), reg);
992 } 995 }
993 996
994 // Go to the next object in the prototype chain. 997 // Go to the next object in the prototype chain.
995 current = prototype; 998 current = prototype;
996 } 999 }
997 ASSERT(current == holder); 1000 ASSERT(current == holder);
998 1001
999 // Log the check depth. 1002 // Log the check depth.
1000 LOG(IntEvent("check-maps-depth", depth + 1)); 1003 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1001 1004
1002 // Check the holder map. 1005 // Check the holder map.
1003 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1006 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1004 Immediate(Handle<Map>(holder->map()))); 1007 Immediate(Handle<Map>(holder->map())));
1005 __ j(not_equal, miss, not_taken); 1008 __ j(not_equal, miss, not_taken);
1006 1009
1007 // Perform security check for access to the global object. 1010 // Perform security check for access to the global object.
1008 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1011 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1009 if (holder->IsJSGlobalProxy()) { 1012 if (holder->IsJSGlobalProxy()) {
1010 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1013 __ CheckAccessGlobalProxy(reg, scratch1, miss);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 1076
1074 // Insert additional parameters into the stack frame above return address. 1077 // Insert additional parameters into the stack frame above return address.
1075 ASSERT(!scratch3.is(reg)); 1078 ASSERT(!scratch3.is(reg));
1076 __ pop(scratch3); // Get return address to place it below. 1079 __ pop(scratch3); // Get return address to place it below.
1077 1080
1078 __ push(receiver); // receiver 1081 __ push(receiver); // receiver
1079 __ mov(scratch2, Operand(esp)); 1082 __ mov(scratch2, Operand(esp));
1080 ASSERT(!scratch2.is(reg)); 1083 ASSERT(!scratch2.is(reg));
1081 __ push(reg); // holder 1084 __ push(reg); // holder
1082 // Push data from AccessorInfo. 1085 // Push data from AccessorInfo.
1083 if (Heap::InNewSpace(callback_handle->data())) { 1086 if (HEAP->InNewSpace(callback_handle->data())) {
1084 __ mov(scratch1, Immediate(callback_handle)); 1087 __ mov(scratch1, Immediate(callback_handle));
1085 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); 1088 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
1086 } else { 1089 } else {
1087 __ push(Immediate(Handle<Object>(callback_handle->data()))); 1090 __ push(Immediate(Handle<Object>(callback_handle->data())));
1088 } 1091 }
1089 1092
1090 // Save a pointer to where we pushed the arguments pointer. 1093 // Save a pointer to where we pushed the arguments pointer.
1091 // This will be passed as the const AccessorInfo& to the C++ callback. 1094 // This will be passed as the const AccessorInfo& to the C++ callback.
1092 __ push(scratch2); 1095 __ push(scratch2);
1093 1096
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 // of this method.) 1200 // of this method.)
1198 CompileCallLoadPropertyWithInterceptor(masm(), 1201 CompileCallLoadPropertyWithInterceptor(masm(),
1199 receiver, 1202 receiver,
1200 holder_reg, 1203 holder_reg,
1201 name_reg, 1204 name_reg,
1202 interceptor_holder); 1205 interceptor_holder);
1203 1206
1204 // Check if interceptor provided a value for property. If it's 1207 // Check if interceptor provided a value for property. If it's
1205 // the case, return immediately. 1208 // the case, return immediately.
1206 Label interceptor_failed; 1209 Label interceptor_failed;
1207 __ cmp(eax, Factory::no_interceptor_result_sentinel()); 1210 __ cmp(eax, FACTORY->no_interceptor_result_sentinel());
1208 __ j(equal, &interceptor_failed); 1211 __ j(equal, &interceptor_failed);
1209 __ LeaveInternalFrame(); 1212 __ LeaveInternalFrame();
1210 __ ret(0); 1213 __ ret(0);
1211 1214
1212 __ bind(&interceptor_failed); 1215 __ bind(&interceptor_failed);
1213 __ pop(name_reg); 1216 __ pop(name_reg);
1214 __ pop(holder_reg); 1217 __ pop(holder_reg);
1215 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { 1218 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
1216 __ pop(receiver); 1219 __ pop(receiver);
1217 } 1220 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 Label* miss) { 1321 Label* miss) {
1319 // Get the value from the cell. 1322 // Get the value from the cell.
1320 if (Serializer::enabled()) { 1323 if (Serializer::enabled()) {
1321 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); 1324 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell)));
1322 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); 1325 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
1323 } else { 1326 } else {
1324 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 1327 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
1325 } 1328 }
1326 1329
1327 // Check that the cell contains the same function. 1330 // Check that the cell contains the same function.
1328 if (Heap::InNewSpace(function)) { 1331 if (HEAP->InNewSpace(function)) {
1329 // We can't embed a pointer to a function in new space so we have 1332 // We can't embed a pointer to a function in new space so we have
1330 // to verify that the shared function info is unchanged. This has 1333 // to verify that the shared function info is unchanged. This has
1331 // the nice side effect that multiple closures based on the same 1334 // the nice side effect that multiple closures based on the same
1332 // function can all use this call IC. Before we load through the 1335 // function can all use this call IC. Before we load through the
1333 // function, we have to verify that it still is a function. 1336 // function, we have to verify that it still is a function.
1334 __ test(edi, Immediate(kSmiTagMask)); 1337 __ test(edi, Immediate(kSmiTagMask));
1335 __ j(zero, miss, not_taken); 1338 __ j(zero, miss, not_taken);
1336 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1339 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1337 __ j(not_equal, miss, not_taken); 1340 __ j(not_equal, miss, not_taken);
1338 1341
1339 // Check the shared function info. Make sure it hasn't changed. 1342 // Check the shared function info. Make sure it hasn't changed.
1340 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1343 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1341 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1344 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1342 __ j(not_equal, miss, not_taken); 1345 __ j(not_equal, miss, not_taken);
1343 } else { 1346 } else {
1344 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1347 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
1345 __ j(not_equal, miss, not_taken); 1348 __ j(not_equal, miss, not_taken);
1346 } 1349 }
1347 } 1350 }
1348 1351
1349 1352
1350 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1353 MaybeObject* CallStubCompiler::GenerateMissBranch() {
1351 MaybeObject* maybe_obj = StubCache::ComputeCallMiss(arguments().immediate(), 1354 MaybeObject* maybe_obj =
1352 kind_); 1355 Isolate::Current()->stub_cache()->ComputeCallMiss(
1356 arguments().immediate(), kind_);
1353 Object* obj; 1357 Object* obj;
1354 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1358 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1355 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1359 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1356 return obj; 1360 return obj;
1357 } 1361 }
1358 1362
1359 1363
1360 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( 1364 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField(
1361 JSObject* object, 1365 JSObject* object,
1362 JSObject* holder, 1366 JSObject* holder,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 String* name) { 1426 String* name) {
1423 // ----------- S t a t e ------------- 1427 // ----------- S t a t e -------------
1424 // -- ecx : name 1428 // -- ecx : name
1425 // -- esp[0] : return address 1429 // -- esp[0] : return address
1426 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1430 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1427 // -- ... 1431 // -- ...
1428 // -- esp[(argc + 1) * 4] : receiver 1432 // -- esp[(argc + 1) * 4] : receiver
1429 // ----------------------------------- 1433 // -----------------------------------
1430 1434
1431 // If object is not an array, bail out to regular call. 1435 // If object is not an array, bail out to regular call.
1432 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); 1436 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
1433 1437
1434 Label miss; 1438 Label miss;
1435 1439
1436 GenerateNameCheck(name, &miss); 1440 GenerateNameCheck(name, &miss);
1437 1441
1438 // Get the receiver from the stack. 1442 // Get the receiver from the stack.
1439 const int argc = arguments().immediate(); 1443 const int argc = arguments().immediate();
1440 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1444 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1441 1445
1442 // Check that the receiver isn't a smi. 1446 // Check that the receiver isn't a smi.
1443 __ test(edx, Immediate(kSmiTagMask)); 1447 __ test(edx, Immediate(kSmiTagMask));
1444 __ j(zero, &miss); 1448 __ j(zero, &miss);
1445 1449
1446 CheckPrototypes(JSObject::cast(object), edx, 1450 CheckPrototypes(JSObject::cast(object), edx,
1447 holder, ebx, 1451 holder, ebx,
1448 eax, edi, name, &miss); 1452 eax, edi, name, &miss);
1449 1453
1450 if (argc == 0) { 1454 if (argc == 0) {
1451 // Noop, return the length. 1455 // Noop, return the length.
1452 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1456 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1453 __ ret((argc + 1) * kPointerSize); 1457 __ ret((argc + 1) * kPointerSize);
1454 } else { 1458 } else {
1455 Label call_builtin; 1459 Label call_builtin;
1456 1460
1457 // Get the elements array of the object. 1461 // Get the elements array of the object.
1458 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1462 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1459 1463
1460 // Check that the elements are in fast mode and writable. 1464 // Check that the elements are in fast mode and writable.
1461 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1465 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1462 Immediate(Factory::fixed_array_map())); 1466 Immediate(FACTORY->fixed_array_map()));
1463 __ j(not_equal, &call_builtin); 1467 __ j(not_equal, &call_builtin);
1464 1468
1465 if (argc == 1) { // Otherwise fall through to call builtin. 1469 if (argc == 1) { // Otherwise fall through to call builtin.
1466 Label exit, attempt_to_grow_elements; 1470 Label exit, attempt_to_grow_elements;
1467 NearLabel with_write_barrier; 1471 NearLabel with_write_barrier;
1468 1472
1469 // Get the array's length into eax and calculate new length. 1473 // Get the array's length into eax and calculate new length.
1470 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1474 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1471 STATIC_ASSERT(kSmiTagSize == 1); 1475 STATIC_ASSERT(kSmiTagSize == 1);
1472 STATIC_ASSERT(kSmiTag == 0); 1476 STATIC_ASSERT(kSmiTag == 0);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 1537
1534 // We fit and could grow elements. 1538 // We fit and could grow elements.
1535 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); 1539 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
1536 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1540 __ mov(ecx, Operand(esp, argc * kPointerSize));
1537 1541
1538 // Push the argument... 1542 // Push the argument...
1539 __ mov(Operand(edx, 0), ecx); 1543 __ mov(Operand(edx, 0), ecx);
1540 // ... and fill the rest with holes. 1544 // ... and fill the rest with holes.
1541 for (int i = 1; i < kAllocationDelta; i++) { 1545 for (int i = 1; i < kAllocationDelta; i++) {
1542 __ mov(Operand(edx, i * kPointerSize), 1546 __ mov(Operand(edx, i * kPointerSize),
1543 Immediate(Factory::the_hole_value())); 1547 Immediate(FACTORY->the_hole_value()));
1544 } 1548 }
1545 1549
1546 // We know the elements array is in new space so we don't need the 1550 // We know the elements array is in new space so we don't need the
1547 // remembered set, but we just pushed a value onto it so we may have to 1551 // remembered set, but we just pushed a value onto it so we may have to
1548 // tell the incremental marker to rescan the object that we just grew. We 1552 // tell the incremental marker to rescan the object that we just grew. We
1549 // don't need to worry about the holes because they are in old space and 1553 // don't need to worry about the holes because they are in old space and
1550 // already marked black. 1554 // already marked black.
1551 __ mov(edi, ebx); 1555 __ mov(edi, ebx);
1552 __ RecordWrite(edi, edx, ecx, OMIT_REMEMBERED_SET, kDontSaveFPRegs); 1556 __ RecordWrite(edi, edx, ecx, OMIT_REMEMBERED_SET, kDontSaveFPRegs);
1553 1557
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 String* name) { 1591 String* name) {
1588 // ----------- S t a t e ------------- 1592 // ----------- S t a t e -------------
1589 // -- ecx : name 1593 // -- ecx : name
1590 // -- esp[0] : return address 1594 // -- esp[0] : return address
1591 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1595 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1592 // -- ... 1596 // -- ...
1593 // -- esp[(argc + 1) * 4] : receiver 1597 // -- esp[(argc + 1) * 4] : receiver
1594 // ----------------------------------- 1598 // -----------------------------------
1595 1599
1596 // If object is not an array, bail out to regular call. 1600 // If object is not an array, bail out to regular call.
1597 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); 1601 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
1598 1602
1599 Label miss, return_undefined, call_builtin; 1603 Label miss, return_undefined, call_builtin;
1600 1604
1601 GenerateNameCheck(name, &miss); 1605 GenerateNameCheck(name, &miss);
1602 1606
1603 // Get the receiver from the stack. 1607 // Get the receiver from the stack.
1604 const int argc = arguments().immediate(); 1608 const int argc = arguments().immediate();
1605 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1609 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1606 1610
1607 // Check that the receiver isn't a smi. 1611 // Check that the receiver isn't a smi.
1608 __ test(edx, Immediate(kSmiTagMask)); 1612 __ test(edx, Immediate(kSmiTagMask));
1609 __ j(zero, &miss); 1613 __ j(zero, &miss);
1610 CheckPrototypes(JSObject::cast(object), edx, 1614 CheckPrototypes(JSObject::cast(object), edx,
1611 holder, ebx, 1615 holder, ebx,
1612 eax, edi, name, &miss); 1616 eax, edi, name, &miss);
1613 1617
1614 // Get the elements array of the object. 1618 // Get the elements array of the object.
1615 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1619 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1616 1620
1617 // Check that the elements are in fast mode and writable. 1621 // Check that the elements are in fast mode and writable.
1618 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1622 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1619 Immediate(Factory::fixed_array_map())); 1623 Immediate(FACTORY->fixed_array_map()));
1620 __ j(not_equal, &call_builtin); 1624 __ j(not_equal, &call_builtin);
1621 1625
1622 // Get the array's length into ecx and calculate new length. 1626 // Get the array's length into ecx and calculate new length.
1623 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); 1627 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset));
1624 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); 1628 __ sub(Operand(ecx), Immediate(Smi::FromInt(1)));
1625 __ j(negative, &return_undefined); 1629 __ j(negative, &return_undefined);
1626 1630
1627 // Get the last element. 1631 // Get the last element.
1628 STATIC_ASSERT(kSmiTagSize == 1); 1632 STATIC_ASSERT(kSmiTagSize == 1);
1629 STATIC_ASSERT(kSmiTag == 0); 1633 STATIC_ASSERT(kSmiTag == 0);
1630 __ mov(eax, FieldOperand(ebx, 1634 __ mov(eax, FieldOperand(ebx,
1631 ecx, times_half_pointer_size, 1635 ecx, times_half_pointer_size,
1632 FixedArray::kHeaderSize)); 1636 FixedArray::kHeaderSize));
1633 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); 1637 __ cmp(Operand(eax), Immediate(FACTORY->the_hole_value()));
1634 __ j(equal, &call_builtin); 1638 __ j(equal, &call_builtin);
1635 1639
1636 // Set the array's length. 1640 // Set the array's length.
1637 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); 1641 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
1638 1642
1639 // Fill with the hole. 1643 // Fill with the hole.
1640 __ mov(FieldOperand(ebx, 1644 __ mov(FieldOperand(ebx,
1641 ecx, times_half_pointer_size, 1645 ecx, times_half_pointer_size,
1642 FixedArray::kHeaderSize), 1646 FixedArray::kHeaderSize),
1643 Immediate(Factory::the_hole_value())); 1647 Immediate(FACTORY->the_hole_value()));
1644 __ ret((argc + 1) * kPointerSize); 1648 __ ret((argc + 1) * kPointerSize);
1645 1649
1646 __ bind(&return_undefined); 1650 __ bind(&return_undefined);
1647 __ mov(eax, Immediate(Factory::undefined_value())); 1651 __ mov(eax, Immediate(FACTORY->undefined_value()));
1648 __ ret((argc + 1) * kPointerSize); 1652 __ ret((argc + 1) * kPointerSize);
1649 1653
1650 __ bind(&call_builtin); 1654 __ bind(&call_builtin);
1651 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), 1655 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop),
1652 argc + 1, 1656 argc + 1,
1653 1); 1657 1);
1654 1658
1655 __ bind(&miss); 1659 __ bind(&miss);
1656 Object* obj; 1660 Object* obj;
1657 { MaybeObject* maybe_obj = GenerateMissBranch(); 1661 { MaybeObject* maybe_obj = GenerateMissBranch();
(...skipping 13 matching lines...) Expand all
1671 String* name) { 1675 String* name) {
1672 // ----------- S t a t e ------------- 1676 // ----------- S t a t e -------------
1673 // -- ecx : function name 1677 // -- ecx : function name
1674 // -- esp[0] : return address 1678 // -- esp[0] : return address
1675 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1679 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1676 // -- ... 1680 // -- ...
1677 // -- esp[(argc + 1) * 4] : receiver 1681 // -- esp[(argc + 1) * 4] : receiver
1678 // ----------------------------------- 1682 // -----------------------------------
1679 1683
1680 // If object is not a string, bail out to regular call. 1684 // If object is not a string, bail out to regular call.
1681 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); 1685 if (!object->IsString() || cell != NULL) return HEAP->undefined_value();
1682 1686
1683 const int argc = arguments().immediate(); 1687 const int argc = arguments().immediate();
1684 1688
1685 Label miss; 1689 Label miss;
1686 Label name_miss; 1690 Label name_miss;
1687 Label index_out_of_range; 1691 Label index_out_of_range;
1688 Label* index_out_of_range_label = &index_out_of_range; 1692 Label* index_out_of_range_label = &index_out_of_range;
1689 1693
1690 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1694 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
1691 index_out_of_range_label = &miss; 1695 index_out_of_range_label = &miss;
(...skipping 11 matching lines...) Expand all
1703 ebx, edx, edi, name, &miss); 1707 ebx, edx, edi, name, &miss);
1704 1708
1705 Register receiver = ebx; 1709 Register receiver = ebx;
1706 Register index = edi; 1710 Register index = edi;
1707 Register scratch = edx; 1711 Register scratch = edx;
1708 Register result = eax; 1712 Register result = eax;
1709 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 1713 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
1710 if (argc > 0) { 1714 if (argc > 0) {
1711 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 1715 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
1712 } else { 1716 } else {
1713 __ Set(index, Immediate(Factory::undefined_value())); 1717 __ Set(index, Immediate(FACTORY->undefined_value()));
1714 } 1718 }
1715 1719
1716 StringCharCodeAtGenerator char_code_at_generator(receiver, 1720 StringCharCodeAtGenerator char_code_at_generator(receiver,
1717 index, 1721 index,
1718 scratch, 1722 scratch,
1719 result, 1723 result,
1720 &miss, // When not a string. 1724 &miss, // When not a string.
1721 &miss, // When not a number. 1725 &miss, // When not a number.
1722 index_out_of_range_label, 1726 index_out_of_range_label,
1723 STRING_INDEX_IS_NUMBER); 1727 STRING_INDEX_IS_NUMBER);
1724 char_code_at_generator.GenerateFast(masm()); 1728 char_code_at_generator.GenerateFast(masm());
1725 __ ret((argc + 1) * kPointerSize); 1729 __ ret((argc + 1) * kPointerSize);
1726 1730
1727 StubRuntimeCallHelper call_helper; 1731 StubRuntimeCallHelper call_helper;
1728 char_code_at_generator.GenerateSlow(masm(), call_helper); 1732 char_code_at_generator.GenerateSlow(masm(), call_helper);
1729 1733
1730 if (index_out_of_range.is_linked()) { 1734 if (index_out_of_range.is_linked()) {
1731 __ bind(&index_out_of_range); 1735 __ bind(&index_out_of_range);
1732 __ Set(eax, Immediate(Factory::nan_value())); 1736 __ Set(eax, Immediate(FACTORY->nan_value()));
1733 __ ret((argc + 1) * kPointerSize); 1737 __ ret((argc + 1) * kPointerSize);
1734 } 1738 }
1735 1739
1736 __ bind(&miss); 1740 __ bind(&miss);
1737 // Restore function name in ecx. 1741 // Restore function name in ecx.
1738 __ Set(ecx, Immediate(Handle<String>(name))); 1742 __ Set(ecx, Immediate(Handle<String>(name)));
1739 __ bind(&name_miss); 1743 __ bind(&name_miss);
1740 Object* obj; 1744 Object* obj;
1741 { MaybeObject* maybe_obj = GenerateMissBranch(); 1745 { MaybeObject* maybe_obj = GenerateMissBranch();
1742 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1746 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 12 matching lines...) Expand all
1755 String* name) { 1759 String* name) {
1756 // ----------- S t a t e ------------- 1760 // ----------- S t a t e -------------
1757 // -- ecx : function name 1761 // -- ecx : function name
1758 // -- esp[0] : return address 1762 // -- esp[0] : return address
1759 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1763 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1760 // -- ... 1764 // -- ...
1761 // -- esp[(argc + 1) * 4] : receiver 1765 // -- esp[(argc + 1) * 4] : receiver
1762 // ----------------------------------- 1766 // -----------------------------------
1763 1767
1764 // If object is not a string, bail out to regular call. 1768 // If object is not a string, bail out to regular call.
1765 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); 1769 if (!object->IsString() || cell != NULL) return HEAP->undefined_value();
1766 1770
1767 const int argc = arguments().immediate(); 1771 const int argc = arguments().immediate();
1768 1772
1769 Label miss; 1773 Label miss;
1770 Label name_miss; 1774 Label name_miss;
1771 Label index_out_of_range; 1775 Label index_out_of_range;
1772 Label* index_out_of_range_label = &index_out_of_range; 1776 Label* index_out_of_range_label = &index_out_of_range;
1773 1777
1774 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1778 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
1775 index_out_of_range_label = &miss; 1779 index_out_of_range_label = &miss;
(...skipping 12 matching lines...) Expand all
1788 1792
1789 Register receiver = eax; 1793 Register receiver = eax;
1790 Register index = edi; 1794 Register index = edi;
1791 Register scratch1 = ebx; 1795 Register scratch1 = ebx;
1792 Register scratch2 = edx; 1796 Register scratch2 = edx;
1793 Register result = eax; 1797 Register result = eax;
1794 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 1798 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
1795 if (argc > 0) { 1799 if (argc > 0) {
1796 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 1800 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
1797 } else { 1801 } else {
1798 __ Set(index, Immediate(Factory::undefined_value())); 1802 __ Set(index, Immediate(FACTORY->undefined_value()));
1799 } 1803 }
1800 1804
1801 StringCharAtGenerator char_at_generator(receiver, 1805 StringCharAtGenerator char_at_generator(receiver,
1802 index, 1806 index,
1803 scratch1, 1807 scratch1,
1804 scratch2, 1808 scratch2,
1805 result, 1809 result,
1806 &miss, // When not a string. 1810 &miss, // When not a string.
1807 &miss, // When not a number. 1811 &miss, // When not a number.
1808 index_out_of_range_label, 1812 index_out_of_range_label,
1809 STRING_INDEX_IS_NUMBER); 1813 STRING_INDEX_IS_NUMBER);
1810 char_at_generator.GenerateFast(masm()); 1814 char_at_generator.GenerateFast(masm());
1811 __ ret((argc + 1) * kPointerSize); 1815 __ ret((argc + 1) * kPointerSize);
1812 1816
1813 StubRuntimeCallHelper call_helper; 1817 StubRuntimeCallHelper call_helper;
1814 char_at_generator.GenerateSlow(masm(), call_helper); 1818 char_at_generator.GenerateSlow(masm(), call_helper);
1815 1819
1816 if (index_out_of_range.is_linked()) { 1820 if (index_out_of_range.is_linked()) {
1817 __ bind(&index_out_of_range); 1821 __ bind(&index_out_of_range);
1818 __ Set(eax, Immediate(Factory::empty_string())); 1822 __ Set(eax, Immediate(FACTORY->empty_string()));
1819 __ ret((argc + 1) * kPointerSize); 1823 __ ret((argc + 1) * kPointerSize);
1820 } 1824 }
1821 1825
1822 __ bind(&miss); 1826 __ bind(&miss);
1823 // Restore function name in ecx. 1827 // Restore function name in ecx.
1824 __ Set(ecx, Immediate(Handle<String>(name))); 1828 __ Set(ecx, Immediate(Handle<String>(name)));
1825 __ bind(&name_miss); 1829 __ bind(&name_miss);
1826 Object* obj; 1830 Object* obj;
1827 { MaybeObject* maybe_obj = GenerateMissBranch(); 1831 { MaybeObject* maybe_obj = GenerateMissBranch();
1828 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1832 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 15 matching lines...) Expand all
1844 // -- esp[0] : return address 1848 // -- esp[0] : return address
1845 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1849 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1846 // -- ... 1850 // -- ...
1847 // -- esp[(argc + 1) * 4] : receiver 1851 // -- esp[(argc + 1) * 4] : receiver
1848 // ----------------------------------- 1852 // -----------------------------------
1849 1853
1850 const int argc = arguments().immediate(); 1854 const int argc = arguments().immediate();
1851 1855
1852 // If the object is not a JSObject or we got an unexpected number of 1856 // If the object is not a JSObject or we got an unexpected number of
1853 // arguments, bail out to the regular call. 1857 // arguments, bail out to the regular call.
1854 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); 1858 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
1855 1859
1856 Label miss; 1860 Label miss;
1857 GenerateNameCheck(name, &miss); 1861 GenerateNameCheck(name, &miss);
1858 1862
1859 if (cell == NULL) { 1863 if (cell == NULL) {
1860 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1864 __ mov(edx, Operand(esp, 2 * kPointerSize));
1861 1865
1862 STATIC_ASSERT(kSmiTag == 0); 1866 STATIC_ASSERT(kSmiTag == 0);
1863 __ test(edx, Immediate(kSmiTagMask)); 1867 __ test(edx, Immediate(kSmiTagMask));
1864 __ j(zero, &miss); 1868 __ j(zero, &miss);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 JSFunction* function, 1918 JSFunction* function,
1915 String* name) { 1919 String* name) {
1916 // ----------- S t a t e ------------- 1920 // ----------- S t a t e -------------
1917 // -- ecx : name 1921 // -- ecx : name
1918 // -- esp[0] : return address 1922 // -- esp[0] : return address
1919 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1923 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1920 // -- ... 1924 // -- ...
1921 // -- esp[(argc + 1) * 4] : receiver 1925 // -- esp[(argc + 1) * 4] : receiver
1922 // ----------------------------------- 1926 // -----------------------------------
1923 1927
1924 if (!CpuFeatures::IsSupported(SSE2)) return Heap::undefined_value(); 1928 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2))
1929 return HEAP->undefined_value();
1925 CpuFeatures::Scope use_sse2(SSE2); 1930 CpuFeatures::Scope use_sse2(SSE2);
1926 1931
1927 const int argc = arguments().immediate(); 1932 const int argc = arguments().immediate();
1928 1933
1929 // If the object is not a JSObject or we got an unexpected number of 1934 // If the object is not a JSObject or we got an unexpected number of
1930 // arguments, bail out to the regular call. 1935 // arguments, bail out to the regular call.
1931 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); 1936 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
1932 1937
1933 Label miss; 1938 Label miss;
1934 GenerateNameCheck(name, &miss); 1939 GenerateNameCheck(name, &miss);
1935 1940
1936 if (cell == NULL) { 1941 if (cell == NULL) {
1937 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1942 __ mov(edx, Operand(esp, 2 * kPointerSize));
1938 1943
1939 STATIC_ASSERT(kSmiTag == 0); 1944 STATIC_ASSERT(kSmiTag == 0);
1940 __ test(edx, Immediate(kSmiTagMask)); 1945 __ test(edx, Immediate(kSmiTagMask));
1941 __ j(zero, &miss); 1946 __ j(zero, &miss);
(...skipping 10 matching lines...) Expand all
1952 __ mov(eax, Operand(esp, 1 * kPointerSize)); 1957 __ mov(eax, Operand(esp, 1 * kPointerSize));
1953 1958
1954 // Check if the argument is a smi. 1959 // Check if the argument is a smi.
1955 Label smi; 1960 Label smi;
1956 STATIC_ASSERT(kSmiTag == 0); 1961 STATIC_ASSERT(kSmiTag == 0);
1957 __ test(eax, Immediate(kSmiTagMask)); 1962 __ test(eax, Immediate(kSmiTagMask));
1958 __ j(zero, &smi); 1963 __ j(zero, &smi);
1959 1964
1960 // Check if the argument is a heap number and load its value into xmm0. 1965 // Check if the argument is a heap number and load its value into xmm0.
1961 Label slow; 1966 Label slow;
1962 __ CheckMap(eax, Factory::heap_number_map(), &slow, true); 1967 __ CheckMap(eax, FACTORY->heap_number_map(), &slow, true);
1963 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 1968 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
1964 1969
1965 // Check if the argument is strictly positive. Note this also 1970 // Check if the argument is strictly positive. Note this also
1966 // discards NaN. 1971 // discards NaN.
1967 __ xorpd(xmm1, xmm1); 1972 __ xorpd(xmm1, xmm1);
1968 __ ucomisd(xmm0, xmm1); 1973 __ ucomisd(xmm0, xmm1);
1969 __ j(below_equal, &slow); 1974 __ j(below_equal, &slow);
1970 1975
1971 // Do a truncating conversion. 1976 // Do a truncating conversion.
1972 __ cvttsd2si(eax, Operand(xmm0)); 1977 __ cvttsd2si(eax, Operand(xmm0));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2045 // -- esp[0] : return address 2050 // -- esp[0] : return address
2046 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2051 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2047 // -- ... 2052 // -- ...
2048 // -- esp[(argc + 1) * 4] : receiver 2053 // -- esp[(argc + 1) * 4] : receiver
2049 // ----------------------------------- 2054 // -----------------------------------
2050 2055
2051 const int argc = arguments().immediate(); 2056 const int argc = arguments().immediate();
2052 2057
2053 // If the object is not a JSObject or we got an unexpected number of 2058 // If the object is not a JSObject or we got an unexpected number of
2054 // arguments, bail out to the regular call. 2059 // arguments, bail out to the regular call.
2055 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); 2060 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
2056 2061
2057 Label miss; 2062 Label miss;
2058 GenerateNameCheck(name, &miss); 2063 GenerateNameCheck(name, &miss);
2059 2064
2060 if (cell == NULL) { 2065 if (cell == NULL) {
2061 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2066 __ mov(edx, Operand(esp, 2 * kPointerSize));
2062 2067
2063 STATIC_ASSERT(kSmiTag == 0); 2068 STATIC_ASSERT(kSmiTag == 0);
2064 __ test(edx, Immediate(kSmiTagMask)); 2069 __ test(edx, Immediate(kSmiTagMask));
2065 __ j(zero, &miss); 2070 __ j(zero, &miss);
(...skipping 30 matching lines...) Expand all
2096 // This only happens for the most negative smi. 2101 // This only happens for the most negative smi.
2097 Label slow; 2102 Label slow;
2098 __ j(negative, &slow); 2103 __ j(negative, &slow);
2099 2104
2100 // Smi case done. 2105 // Smi case done.
2101 __ ret(2 * kPointerSize); 2106 __ ret(2 * kPointerSize);
2102 2107
2103 // Check if the argument is a heap number and load its exponent and 2108 // Check if the argument is a heap number and load its exponent and
2104 // sign into ebx. 2109 // sign into ebx.
2105 __ bind(&not_smi); 2110 __ bind(&not_smi);
2106 __ CheckMap(eax, Factory::heap_number_map(), &slow, true); 2111 __ CheckMap(eax, FACTORY->heap_number_map(), &slow, true);
2107 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset)); 2112 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset));
2108 2113
2109 // Check the sign of the argument. If the argument is positive, 2114 // Check the sign of the argument. If the argument is positive,
2110 // just return it. 2115 // just return it.
2111 Label negative_sign; 2116 Label negative_sign;
2112 __ test(ebx, Immediate(HeapNumber::kSignMask)); 2117 __ test(ebx, Immediate(HeapNumber::kSignMask));
2113 __ j(not_zero, &negative_sign); 2118 __ j(not_zero, &negative_sign);
2114 __ ret(2 * kPointerSize); 2119 __ ret(2 * kPointerSize);
2115 2120
2116 // If the argument is negative, clear the sign, and return a new 2121 // If the argument is negative, clear the sign, and return a new
(...skipping 26 matching lines...) Expand all
2143 MaybeObject* CallStubCompiler::CompileFastApiCall( 2148 MaybeObject* CallStubCompiler::CompileFastApiCall(
2144 const CallOptimization& optimization, 2149 const CallOptimization& optimization,
2145 Object* object, 2150 Object* object,
2146 JSObject* holder, 2151 JSObject* holder,
2147 JSGlobalPropertyCell* cell, 2152 JSGlobalPropertyCell* cell,
2148 JSFunction* function, 2153 JSFunction* function,
2149 String* name) { 2154 String* name) {
2150 ASSERT(optimization.is_simple_api_call()); 2155 ASSERT(optimization.is_simple_api_call());
2151 // Bail out if object is a global object as we don't want to 2156 // Bail out if object is a global object as we don't want to
2152 // repatch it to global receiver. 2157 // repatch it to global receiver.
2153 if (object->IsGlobalObject()) return Heap::undefined_value(); 2158 if (object->IsGlobalObject()) return HEAP->undefined_value();
2154 if (cell != NULL) return Heap::undefined_value(); 2159 if (cell != NULL) return HEAP->undefined_value();
2155 int depth = optimization.GetPrototypeDepthOfExpectedType( 2160 int depth = optimization.GetPrototypeDepthOfExpectedType(
2156 JSObject::cast(object), holder); 2161 JSObject::cast(object), holder);
2157 if (depth == kInvalidProtoDepth) return Heap::undefined_value(); 2162 if (depth == kInvalidProtoDepth) return HEAP->undefined_value();
2158 2163
2159 Label miss, miss_before_stack_reserved; 2164 Label miss, miss_before_stack_reserved;
2160 2165
2161 GenerateNameCheck(name, &miss_before_stack_reserved); 2166 GenerateNameCheck(name, &miss_before_stack_reserved);
2162 2167
2163 // Get the receiver from the stack. 2168 // Get the receiver from the stack.
2164 const int argc = arguments().immediate(); 2169 const int argc = arguments().immediate();
2165 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2170 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2166 2171
2167 // Check that the receiver isn't a smi. 2172 // Check that the receiver isn't a smi.
2168 __ test(edx, Immediate(kSmiTagMask)); 2173 __ test(edx, Immediate(kSmiTagMask));
2169 __ j(zero, &miss_before_stack_reserved, not_taken); 2174 __ j(zero, &miss_before_stack_reserved, not_taken);
2170 2175
2171 __ IncrementCounter(&Counters::call_const, 1); 2176 __ IncrementCounter(COUNTERS->call_const(), 1);
2172 __ IncrementCounter(&Counters::call_const_fast_api, 1); 2177 __ IncrementCounter(COUNTERS->call_const_fast_api(), 1);
2173 2178
2174 // Allocate space for v8::Arguments implicit values. Must be initialized 2179 // Allocate space for v8::Arguments implicit values. Must be initialized
2175 // before calling any runtime function. 2180 // before calling any runtime function.
2176 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); 2181 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2177 2182
2178 // Check that the maps haven't changed and find a Holder as a side effect. 2183 // Check that the maps haven't changed and find a Holder as a side effect.
2179 CheckPrototypes(JSObject::cast(object), edx, holder, 2184 CheckPrototypes(JSObject::cast(object), edx, holder,
2180 ebx, eax, edi, name, depth, &miss); 2185 ebx, eax, edi, name, depth, &miss);
2181 2186
2182 // Move the return address on top of the stack. 2187 // Move the return address on top of the stack.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2238 __ j(zero, &miss, not_taken); 2243 __ j(zero, &miss, not_taken);
2239 } 2244 }
2240 2245
2241 // Make sure that it's okay not to patch the on stack receiver 2246 // Make sure that it's okay not to patch the on stack receiver
2242 // unless we're doing a receiver map check. 2247 // unless we're doing a receiver map check.
2243 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2248 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2244 2249
2245 SharedFunctionInfo* function_info = function->shared(); 2250 SharedFunctionInfo* function_info = function->shared();
2246 switch (check) { 2251 switch (check) {
2247 case RECEIVER_MAP_CHECK: 2252 case RECEIVER_MAP_CHECK:
2248 __ IncrementCounter(&Counters::call_const, 1); 2253 __ IncrementCounter(COUNTERS->call_const(), 1);
2249 2254
2250 // Check that the maps haven't changed. 2255 // Check that the maps haven't changed.
2251 CheckPrototypes(JSObject::cast(object), edx, holder, 2256 CheckPrototypes(JSObject::cast(object), edx, holder,
2252 ebx, eax, edi, name, &miss); 2257 ebx, eax, edi, name, &miss);
2253 2258
2254 // Patch the receiver on the stack with the global proxy if 2259 // Patch the receiver on the stack with the global proxy if
2255 // necessary. 2260 // necessary.
2256 if (object->IsGlobalObject()) { 2261 if (object->IsGlobalObject()) {
2257 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2262 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2258 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2263 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 } 2304 }
2300 2305
2301 case BOOLEAN_CHECK: { 2306 case BOOLEAN_CHECK: {
2302 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2307 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2303 // Calling non-strict non-builtins with a value as the receiver 2308 // Calling non-strict non-builtins with a value as the receiver
2304 // requires boxing. 2309 // requires boxing.
2305 __ jmp(&miss); 2310 __ jmp(&miss);
2306 } else { 2311 } else {
2307 Label fast; 2312 Label fast;
2308 // Check that the object is a boolean. 2313 // Check that the object is a boolean.
2309 __ cmp(edx, Factory::true_value()); 2314 __ cmp(edx, FACTORY->true_value());
2310 __ j(equal, &fast, taken); 2315 __ j(equal, &fast, taken);
2311 __ cmp(edx, Factory::false_value()); 2316 __ cmp(edx, FACTORY->false_value());
2312 __ j(not_equal, &miss, not_taken); 2317 __ j(not_equal, &miss, not_taken);
2313 __ bind(&fast); 2318 __ bind(&fast);
2314 // Check that the maps starting from the prototype haven't changed. 2319 // Check that the maps starting from the prototype haven't changed.
2315 GenerateDirectLoadGlobalFunctionPrototype( 2320 GenerateDirectLoadGlobalFunctionPrototype(
2316 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2321 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
2317 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2322 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
2318 ebx, edx, edi, name, &miss); 2323 ebx, edx, edi, name, &miss);
2319 } 2324 }
2320 break; 2325 break;
2321 } 2326 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 // Patch the receiver on the stack with the global proxy. 2447 // Patch the receiver on the stack with the global proxy.
2443 if (object->IsGlobalObject()) { 2448 if (object->IsGlobalObject()) {
2444 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2449 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2445 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2450 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2446 } 2451 }
2447 2452
2448 // Setup the context (function already in edi). 2453 // Setup the context (function already in edi).
2449 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2454 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2450 2455
2451 // Jump to the cached code (tail call). 2456 // Jump to the cached code (tail call).
2452 __ IncrementCounter(&Counters::call_global_inline, 1); 2457 __ IncrementCounter(COUNTERS->call_global_inline(), 1);
2453 ASSERT(function->is_compiled()); 2458 ASSERT(function->is_compiled());
2454 ParameterCount expected(function->shared()->formal_parameter_count()); 2459 ParameterCount expected(function->shared()->formal_parameter_count());
2455 if (V8::UseCrankshaft()) { 2460 if (V8::UseCrankshaft()) {
2456 // TODO(kasperl): For now, we always call indirectly through the 2461 // TODO(kasperl): For now, we always call indirectly through the
2457 // code field in the function to allow recompilation to take effect 2462 // code field in the function to allow recompilation to take effect
2458 // without changing any of the call sites. 2463 // without changing any of the call sites.
2459 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2464 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2460 expected, arguments(), JUMP_FUNCTION); 2465 expected, arguments(), JUMP_FUNCTION);
2461 } else { 2466 } else {
2462 Handle<Code> code(function->code()); 2467 Handle<Code> code(function->code());
2463 __ InvokeCode(code, expected, arguments(), 2468 __ InvokeCode(code, expected, arguments(),
2464 RelocInfo::CODE_TARGET, JUMP_FUNCTION); 2469 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
2465 } 2470 }
2466 2471
2467 // Handle call cache miss. 2472 // Handle call cache miss.
2468 __ bind(&miss); 2473 __ bind(&miss);
2469 __ IncrementCounter(&Counters::call_global_inline_miss, 1); 2474 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1);
2470 Object* obj; 2475 Object* obj;
2471 { MaybeObject* maybe_obj = GenerateMissBranch(); 2476 { MaybeObject* maybe_obj = GenerateMissBranch();
2472 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2477 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2473 } 2478 }
2474 2479
2475 // Return the generated code. 2480 // Return the generated code.
2476 return GetCode(NORMAL, name); 2481 return GetCode(NORMAL, name);
2477 } 2482 }
2478 2483
2479 2484
(...skipping 13 matching lines...) Expand all
2493 GenerateStoreField(masm(), 2498 GenerateStoreField(masm(),
2494 object, 2499 object,
2495 index, 2500 index,
2496 transition, 2501 transition,
2497 edx, ecx, ebx, 2502 edx, ecx, ebx,
2498 &miss); 2503 &miss);
2499 2504
2500 // Handle store cache miss. 2505 // Handle store cache miss.
2501 __ bind(&miss); 2506 __ bind(&miss);
2502 __ mov(ecx, Immediate(Handle<String>(name))); // restore name 2507 __ mov(ecx, Immediate(Handle<String>(name))); // restore name
2503 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2508 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2509 Builtins::StoreIC_Miss));
2504 __ jmp(ic, RelocInfo::CODE_TARGET); 2510 __ jmp(ic, RelocInfo::CODE_TARGET);
2505 2511
2506 // Return the generated code. 2512 // Return the generated code.
2507 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2513 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2508 } 2514 }
2509 2515
2510 2516
2511 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2517 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object,
2512 AccessorInfo* callback, 2518 AccessorInfo* callback,
2513 String* name) { 2519 String* name) {
(...skipping 30 matching lines...) Expand all
2544 __ push(eax); // value 2550 __ push(eax); // value
2545 __ push(ebx); // restore return address 2551 __ push(ebx); // restore return address
2546 2552
2547 // Do tail-call to the runtime system. 2553 // Do tail-call to the runtime system.
2548 ExternalReference store_callback_property = 2554 ExternalReference store_callback_property =
2549 ExternalReference(IC_Utility(IC::kStoreCallbackProperty)); 2555 ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
2550 __ TailCallExternalReference(store_callback_property, 4, 1); 2556 __ TailCallExternalReference(store_callback_property, 4, 1);
2551 2557
2552 // Handle store cache miss. 2558 // Handle store cache miss.
2553 __ bind(&miss); 2559 __ bind(&miss);
2554 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2560 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2561 Builtins::StoreIC_Miss));
2555 __ jmp(ic, RelocInfo::CODE_TARGET); 2562 __ jmp(ic, RelocInfo::CODE_TARGET);
2556 2563
2557 // Return the generated code. 2564 // Return the generated code.
2558 return GetCode(CALLBACKS, name); 2565 return GetCode(CALLBACKS, name);
2559 } 2566 }
2560 2567
2561 2568
2562 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2569 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
2563 String* name) { 2570 String* name) {
2564 // ----------- S t a t e ------------- 2571 // ----------- S t a t e -------------
(...skipping 29 matching lines...) Expand all
2594 __ push(Immediate(Smi::FromInt(strict_mode_))); 2601 __ push(Immediate(Smi::FromInt(strict_mode_)));
2595 __ push(ebx); // restore return address 2602 __ push(ebx); // restore return address
2596 2603
2597 // Do tail-call to the runtime system. 2604 // Do tail-call to the runtime system.
2598 ExternalReference store_ic_property = 2605 ExternalReference store_ic_property =
2599 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); 2606 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
2600 __ TailCallExternalReference(store_ic_property, 4, 1); 2607 __ TailCallExternalReference(store_ic_property, 4, 1);
2601 2608
2602 // Handle store cache miss. 2609 // Handle store cache miss.
2603 __ bind(&miss); 2610 __ bind(&miss);
2604 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2611 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2612 Builtins::StoreIC_Miss));
2605 __ jmp(ic, RelocInfo::CODE_TARGET); 2613 __ jmp(ic, RelocInfo::CODE_TARGET);
2606 2614
2607 // Return the generated code. 2615 // Return the generated code.
2608 return GetCode(INTERCEPTOR, name); 2616 return GetCode(INTERCEPTOR, name);
2609 } 2617 }
2610 2618
2611 2619
2612 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2620 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
2613 JSGlobalPropertyCell* cell, 2621 JSGlobalPropertyCell* cell,
2614 String* name) { 2622 String* name) {
(...skipping 11 matching lines...) Expand all
2626 __ j(not_equal, &miss, not_taken); 2634 __ j(not_equal, &miss, not_taken);
2627 2635
2628 // Compute the cell operand to use. 2636 // Compute the cell operand to use.
2629 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2637 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2630 Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); 2638 Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
2631 2639
2632 // Check that the value in the cell is not the hole. If it is, this 2640 // Check that the value in the cell is not the hole. If it is, this
2633 // cell could have been deleted and reintroducing the global needs 2641 // cell could have been deleted and reintroducing the global needs
2634 // to update the property details in the property dictionary of the 2642 // to update the property details in the property dictionary of the
2635 // global object. We bail out to the runtime system to do that. 2643 // global object. We bail out to the runtime system to do that.
2636 __ cmp(cell_operand, Factory::the_hole_value()); 2644 __ cmp(cell_operand, FACTORY->the_hole_value());
2637 __ j(equal, &miss); 2645 __ j(equal, &miss);
2638 2646
2639 // Store the value in the cell. 2647 // Store the value in the cell.
2640 __ mov(cell_operand, eax); 2648 __ mov(cell_operand, eax);
2641 Label done; 2649 Label done;
2642 __ test(eax, Immediate(kSmiTagMask)); 2650 __ test(eax, Immediate(kSmiTagMask));
2643 __ j(zero, &done); 2651 __ j(zero, &done);
2644 2652
2645 __ mov(ecx, eax); 2653 __ mov(ecx, eax);
2646 // Cells are always in the remembered set. 2654 // Cells are always in the remembered set.
2647 __ RecordWrite(ebx, edx, ecx, OMIT_REMEMBERED_SET, kDontSaveFPRegs); 2655 __ RecordWrite(ebx, edx, ecx, OMIT_REMEMBERED_SET, kDontSaveFPRegs);
2648 2656
2649 // Return the value (register eax). 2657 // Return the value (register eax).
2650 __ bind(&done); 2658 __ bind(&done);
2651 2659
2652 // Return the value (register eax). 2660 // Return the value (register eax).
2653 __ IncrementCounter(&Counters::named_store_global_inline, 1); 2661 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
2654 __ ret(0); 2662 __ ret(0);
2655 2663
2656 // Handle store cache miss. 2664 // Handle store cache miss.
2657 __ bind(&miss); 2665 __ bind(&miss);
2658 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); 2666 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
2659 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2667 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2668 Builtins::StoreIC_Miss));
2660 __ jmp(ic, RelocInfo::CODE_TARGET); 2669 __ jmp(ic, RelocInfo::CODE_TARGET);
2661 2670
2662 // Return the generated code. 2671 // Return the generated code.
2663 return GetCode(NORMAL, name); 2672 return GetCode(NORMAL, name);
2664 } 2673 }
2665 2674
2666 2675
2667 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2676 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
2668 int index, 2677 int index,
2669 Map* transition, 2678 Map* transition,
2670 String* name) { 2679 String* name) {
2671 // ----------- S t a t e ------------- 2680 // ----------- S t a t e -------------
2672 // -- eax : value 2681 // -- eax : value
2673 // -- ecx : key 2682 // -- ecx : key
2674 // -- edx : receiver 2683 // -- edx : receiver
2675 // -- esp[0] : return address 2684 // -- esp[0] : return address
2676 // ----------------------------------- 2685 // -----------------------------------
2677 Label miss; 2686 Label miss;
2678 2687
2679 __ IncrementCounter(&Counters::keyed_store_field, 1); 2688 __ IncrementCounter(COUNTERS->keyed_store_field(), 1);
2680 2689
2681 // Check that the name has not changed. 2690 // Check that the name has not changed.
2682 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 2691 __ cmp(Operand(ecx), Immediate(Handle<String>(name)));
2683 __ j(not_equal, &miss, not_taken); 2692 __ j(not_equal, &miss, not_taken);
2684 2693
2685 // Generate store field code. Trashes the name register. 2694 // Generate store field code. Trashes the name register.
2686 GenerateStoreField(masm(), 2695 GenerateStoreField(masm(),
2687 object, 2696 object,
2688 index, 2697 index,
2689 transition, 2698 transition,
2690 edx, ecx, ebx, 2699 edx, ecx, ebx,
2691 &miss); 2700 &miss);
2692 2701
2693 // Handle store cache miss. 2702 // Handle store cache miss.
2694 __ bind(&miss); 2703 __ bind(&miss);
2695 __ DecrementCounter(&Counters::keyed_store_field, 1); 2704 __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
2696 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 2705 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2706 Builtins::KeyedStoreIC_Miss));
2697 __ jmp(ic, RelocInfo::CODE_TARGET); 2707 __ jmp(ic, RelocInfo::CODE_TARGET);
2698 2708
2699 // Return the generated code. 2709 // Return the generated code.
2700 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2710 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2701 } 2711 }
2702 2712
2703 2713
2704 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2714 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
2705 JSObject* receiver) { 2715 JSObject* receiver) {
2706 // ----------- S t a t e ------------- 2716 // ----------- S t a t e -------------
(...skipping 13 matching lines...) Expand all
2720 Immediate(Handle<Map>(receiver->map()))); 2730 Immediate(Handle<Map>(receiver->map())));
2721 __ j(not_equal, &miss, not_taken); 2731 __ j(not_equal, &miss, not_taken);
2722 2732
2723 // Check that the key is a smi. 2733 // Check that the key is a smi.
2724 __ test(ecx, Immediate(kSmiTagMask)); 2734 __ test(ecx, Immediate(kSmiTagMask));
2725 __ j(not_zero, &miss, not_taken); 2735 __ j(not_zero, &miss, not_taken);
2726 2736
2727 // Get the elements array and make sure it is a fast element array, not 'cow'. 2737 // Get the elements array and make sure it is a fast element array, not 'cow'.
2728 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 2738 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
2729 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), 2739 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
2730 Immediate(Factory::fixed_array_map())); 2740 Immediate(FACTORY->fixed_array_map()));
2731 __ j(not_equal, &miss, not_taken); 2741 __ j(not_equal, &miss, not_taken);
2732 2742
2733 // Check that the key is within bounds. 2743 // Check that the key is within bounds.
2734 if (receiver->IsJSArray()) { 2744 if (receiver->IsJSArray()) {
2735 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 2745 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
2736 __ j(above_equal, &miss, not_taken); 2746 __ j(above_equal, &miss, not_taken);
2737 } else { 2747 } else {
2738 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis. 2748 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis.
2739 __ j(above_equal, &miss, not_taken); 2749 __ j(above_equal, &miss, not_taken);
2740 } 2750 }
2741 2751
2742 // Do the store and update the write barrier. Make sure to preserve 2752 // Do the store and update the write barrier. Make sure to preserve
2743 // the value in register eax. 2753 // the value in register eax.
2744 __ mov(edx, Operand(eax)); 2754 __ mov(edx, Operand(eax));
2745 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 2755 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2746 __ RecordWrite(edi, 0, edx, ecx, kDontSaveFPRegs); 2756 __ RecordWrite(edi, 0, edx, ecx, kDontSaveFPRegs);
2747 2757
2748 // Done. 2758 // Done.
2749 __ ret(0); 2759 __ ret(0);
2750 2760
2751 // Handle store cache miss. 2761 // Handle store cache miss.
2752 __ bind(&miss); 2762 __ bind(&miss);
2753 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 2763 Handle<Code> ic(
2764 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
2754 __ jmp(ic, RelocInfo::CODE_TARGET); 2765 __ jmp(ic, RelocInfo::CODE_TARGET);
2755 2766
2756 // Return the generated code. 2767 // Return the generated code.
2757 return GetCode(NORMAL, NULL); 2768 return GetCode(NORMAL, NULL);
2758 } 2769 }
2759 2770
2760 2771
2761 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2772 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2762 JSObject* object, 2773 JSObject* object,
2763 JSObject* last) { 2774 JSObject* last) {
(...skipping 24 matching lines...) Expand all
2788 edx, 2799 edx,
2789 &miss); 2800 &miss);
2790 if (cell->IsFailure()) { 2801 if (cell->IsFailure()) {
2791 miss.Unuse(); 2802 miss.Unuse();
2792 return cell; 2803 return cell;
2793 } 2804 }
2794 } 2805 }
2795 2806
2796 // Return undefined if maps of the full prototype chain are still the 2807 // Return undefined if maps of the full prototype chain are still the
2797 // same and no global property with this name contains a value. 2808 // same and no global property with this name contains a value.
2798 __ mov(eax, Factory::undefined_value()); 2809 __ mov(eax, FACTORY->undefined_value());
2799 __ ret(0); 2810 __ ret(0);
2800 2811
2801 __ bind(&miss); 2812 __ bind(&miss);
2802 GenerateLoadMiss(masm(), Code::LOAD_IC); 2813 GenerateLoadMiss(masm(), Code::LOAD_IC);
2803 2814
2804 // Return the generated code. 2815 // Return the generated code.
2805 return GetCode(NONEXISTENT, Heap::empty_string()); 2816 return GetCode(NONEXISTENT, HEAP->empty_string());
2806 } 2817 }
2807 2818
2808 2819
2809 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 2820 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object,
2810 JSObject* holder, 2821 JSObject* holder,
2811 int index, 2822 int index,
2812 String* name) { 2823 String* name) {
2813 // ----------- S t a t e ------------- 2824 // ----------- S t a t e -------------
2814 // -- eax : receiver 2825 // -- eax : receiver
2815 // -- ecx : name 2826 // -- ecx : name
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2932 // Get the value from the cell. 2943 // Get the value from the cell.
2933 if (Serializer::enabled()) { 2944 if (Serializer::enabled()) {
2934 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2945 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2935 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 2946 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
2936 } else { 2947 } else {
2937 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 2948 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
2938 } 2949 }
2939 2950
2940 // Check for deleted property if property can actually be deleted. 2951 // Check for deleted property if property can actually be deleted.
2941 if (!is_dont_delete) { 2952 if (!is_dont_delete) {
2942 __ cmp(ebx, Factory::the_hole_value()); 2953 __ cmp(ebx, FACTORY->the_hole_value());
2943 __ j(equal, &miss, not_taken); 2954 __ j(equal, &miss, not_taken);
2944 } else if (FLAG_debug_code) { 2955 } else if (FLAG_debug_code) {
2945 __ cmp(ebx, Factory::the_hole_value()); 2956 __ cmp(ebx, FACTORY->the_hole_value());
2946 __ Check(not_equal, "DontDelete cells can't contain the hole"); 2957 __ Check(not_equal, "DontDelete cells can't contain the hole");
2947 } 2958 }
2948 2959
2949 __ IncrementCounter(&Counters::named_load_global_stub, 1); 2960 __ IncrementCounter(COUNTERS->named_load_global_stub(), 1);
2950 __ mov(eax, ebx); 2961 __ mov(eax, ebx);
2951 __ ret(0); 2962 __ ret(0);
2952 2963
2953 __ bind(&miss); 2964 __ bind(&miss);
2954 __ IncrementCounter(&Counters::named_load_global_stub_miss, 1); 2965 __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1);
2955 GenerateLoadMiss(masm(), Code::LOAD_IC); 2966 GenerateLoadMiss(masm(), Code::LOAD_IC);
2956 2967
2957 // Return the generated code. 2968 // Return the generated code.
2958 return GetCode(NORMAL, name); 2969 return GetCode(NORMAL, name);
2959 } 2970 }
2960 2971
2961 2972
2962 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 2973 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
2963 JSObject* receiver, 2974 JSObject* receiver,
2964 JSObject* holder, 2975 JSObject* holder,
2965 int index) { 2976 int index) {
2966 // ----------- S t a t e ------------- 2977 // ----------- S t a t e -------------
2967 // -- eax : key 2978 // -- eax : key
2968 // -- edx : receiver 2979 // -- edx : receiver
2969 // -- esp[0] : return address 2980 // -- esp[0] : return address
2970 // ----------------------------------- 2981 // -----------------------------------
2971 Label miss; 2982 Label miss;
2972 2983
2973 __ IncrementCounter(&Counters::keyed_load_field, 1); 2984 __ IncrementCounter(COUNTERS->keyed_load_field(), 1);
2974 2985
2975 // Check that the name has not changed. 2986 // Check that the name has not changed.
2976 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 2987 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
2977 __ j(not_equal, &miss, not_taken); 2988 __ j(not_equal, &miss, not_taken);
2978 2989
2979 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); 2990 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
2980 2991
2981 __ bind(&miss); 2992 __ bind(&miss);
2982 __ DecrementCounter(&Counters::keyed_load_field, 1); 2993 __ DecrementCounter(COUNTERS->keyed_load_field(), 1);
2983 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2994 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2984 2995
2985 // Return the generated code. 2996 // Return the generated code.
2986 return GetCode(FIELD, name); 2997 return GetCode(FIELD, name);
2987 } 2998 }
2988 2999
2989 3000
2990 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( 3001 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
2991 String* name, 3002 String* name,
2992 JSObject* receiver, 3003 JSObject* receiver,
2993 JSObject* holder, 3004 JSObject* holder,
2994 AccessorInfo* callback) { 3005 AccessorInfo* callback) {
2995 // ----------- S t a t e ------------- 3006 // ----------- S t a t e -------------
2996 // -- eax : key 3007 // -- eax : key
2997 // -- edx : receiver 3008 // -- edx : receiver
2998 // -- esp[0] : return address 3009 // -- esp[0] : return address
2999 // ----------------------------------- 3010 // -----------------------------------
3000 Label miss; 3011 Label miss;
3001 3012
3002 __ IncrementCounter(&Counters::keyed_load_callback, 1); 3013 __ IncrementCounter(COUNTERS->keyed_load_callback(), 1);
3003 3014
3004 // Check that the name has not changed. 3015 // Check that the name has not changed.
3005 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3016 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3006 __ j(not_equal, &miss, not_taken); 3017 __ j(not_equal, &miss, not_taken);
3007 3018
3008 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, 3019 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx,
3009 ecx, edi, callback, name, &miss); 3020 ecx, edi, callback, name, &miss);
3010 if (result->IsFailure()) { 3021 if (result->IsFailure()) {
3011 miss.Unuse(); 3022 miss.Unuse();
3012 return result; 3023 return result;
3013 } 3024 }
3014 3025
3015 __ bind(&miss); 3026 __ bind(&miss);
3016 3027
3017 __ DecrementCounter(&Counters::keyed_load_callback, 1); 3028 __ DecrementCounter(COUNTERS->keyed_load_callback(), 1);
3018 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3029 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3019 3030
3020 // Return the generated code. 3031 // Return the generated code.
3021 return GetCode(CALLBACKS, name); 3032 return GetCode(CALLBACKS, name);
3022 } 3033 }
3023 3034
3024 3035
3025 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, 3036 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
3026 JSObject* receiver, 3037 JSObject* receiver,
3027 JSObject* holder, 3038 JSObject* holder,
3028 Object* value) { 3039 Object* value) {
3029 // ----------- S t a t e ------------- 3040 // ----------- S t a t e -------------
3030 // -- eax : key 3041 // -- eax : key
3031 // -- edx : receiver 3042 // -- edx : receiver
3032 // -- esp[0] : return address 3043 // -- esp[0] : return address
3033 // ----------------------------------- 3044 // -----------------------------------
3034 Label miss; 3045 Label miss;
3035 3046
3036 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); 3047 __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1);
3037 3048
3038 // Check that the name has not changed. 3049 // Check that the name has not changed.
3039 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3050 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3040 __ j(not_equal, &miss, not_taken); 3051 __ j(not_equal, &miss, not_taken);
3041 3052
3042 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, 3053 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
3043 value, name, &miss); 3054 value, name, &miss);
3044 __ bind(&miss); 3055 __ bind(&miss);
3045 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); 3056 __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1);
3046 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3057 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3047 3058
3048 // Return the generated code. 3059 // Return the generated code.
3049 return GetCode(CONSTANT_FUNCTION, name); 3060 return GetCode(CONSTANT_FUNCTION, name);
3050 } 3061 }
3051 3062
3052 3063
3053 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3064 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3054 JSObject* holder, 3065 JSObject* holder,
3055 String* name) { 3066 String* name) {
3056 // ----------- S t a t e ------------- 3067 // ----------- S t a t e -------------
3057 // -- eax : key 3068 // -- eax : key
3058 // -- edx : receiver 3069 // -- edx : receiver
3059 // -- esp[0] : return address 3070 // -- esp[0] : return address
3060 // ----------------------------------- 3071 // -----------------------------------
3061 Label miss; 3072 Label miss;
3062 3073
3063 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); 3074 __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1);
3064 3075
3065 // Check that the name has not changed. 3076 // Check that the name has not changed.
3066 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3077 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3067 __ j(not_equal, &miss, not_taken); 3078 __ j(not_equal, &miss, not_taken);
3068 3079
3069 LookupResult lookup; 3080 LookupResult lookup;
3070 LookupPostInterceptor(holder, name, &lookup); 3081 LookupPostInterceptor(holder, name, &lookup);
3071 GenerateLoadInterceptor(receiver, 3082 GenerateLoadInterceptor(receiver,
3072 holder, 3083 holder,
3073 &lookup, 3084 &lookup,
3074 edx, 3085 edx,
3075 eax, 3086 eax,
3076 ecx, 3087 ecx,
3077 ebx, 3088 ebx,
3078 edi, 3089 edi,
3079 name, 3090 name,
3080 &miss); 3091 &miss);
3081 __ bind(&miss); 3092 __ bind(&miss);
3082 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); 3093 __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1);
3083 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3094 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3084 3095
3085 // Return the generated code. 3096 // Return the generated code.
3086 return GetCode(INTERCEPTOR, name); 3097 return GetCode(INTERCEPTOR, name);
3087 } 3098 }
3088 3099
3089 3100
3090 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3101 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
3091 // ----------- S t a t e ------------- 3102 // ----------- S t a t e -------------
3092 // -- eax : key 3103 // -- eax : key
3093 // -- edx : receiver 3104 // -- edx : receiver
3094 // -- esp[0] : return address 3105 // -- esp[0] : return address
3095 // ----------------------------------- 3106 // -----------------------------------
3096 Label miss; 3107 Label miss;
3097 3108
3098 __ IncrementCounter(&Counters::keyed_load_array_length, 1); 3109 __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1);
3099 3110
3100 // Check that the name has not changed. 3111 // Check that the name has not changed.
3101 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3112 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3102 __ j(not_equal, &miss, not_taken); 3113 __ j(not_equal, &miss, not_taken);
3103 3114
3104 GenerateLoadArrayLength(masm(), edx, ecx, &miss); 3115 GenerateLoadArrayLength(masm(), edx, ecx, &miss);
3105 __ bind(&miss); 3116 __ bind(&miss);
3106 __ DecrementCounter(&Counters::keyed_load_array_length, 1); 3117 __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1);
3107 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3118 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3108 3119
3109 // Return the generated code. 3120 // Return the generated code.
3110 return GetCode(CALLBACKS, name); 3121 return GetCode(CALLBACKS, name);
3111 } 3122 }
3112 3123
3113 3124
3114 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3125 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
3115 // ----------- S t a t e ------------- 3126 // ----------- S t a t e -------------
3116 // -- eax : key 3127 // -- eax : key
3117 // -- edx : receiver 3128 // -- edx : receiver
3118 // -- esp[0] : return address 3129 // -- esp[0] : return address
3119 // ----------------------------------- 3130 // -----------------------------------
3120 Label miss; 3131 Label miss;
3121 3132
3122 __ IncrementCounter(&Counters::keyed_load_string_length, 1); 3133 __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1);
3123 3134
3124 // Check that the name has not changed. 3135 // Check that the name has not changed.
3125 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3136 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3126 __ j(not_equal, &miss, not_taken); 3137 __ j(not_equal, &miss, not_taken);
3127 3138
3128 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); 3139 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
3129 __ bind(&miss); 3140 __ bind(&miss);
3130 __ DecrementCounter(&Counters::keyed_load_string_length, 1); 3141 __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1);
3131 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3142 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3132 3143
3133 // Return the generated code. 3144 // Return the generated code.
3134 return GetCode(CALLBACKS, name); 3145 return GetCode(CALLBACKS, name);
3135 } 3146 }
3136 3147
3137 3148
3138 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3149 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
3139 // ----------- S t a t e ------------- 3150 // ----------- S t a t e -------------
3140 // -- eax : key 3151 // -- eax : key
3141 // -- edx : receiver 3152 // -- edx : receiver
3142 // -- esp[0] : return address 3153 // -- esp[0] : return address
3143 // ----------------------------------- 3154 // -----------------------------------
3144 Label miss; 3155 Label miss;
3145 3156
3146 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); 3157 __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
3147 3158
3148 // Check that the name has not changed. 3159 // Check that the name has not changed.
3149 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3160 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3150 __ j(not_equal, &miss, not_taken); 3161 __ j(not_equal, &miss, not_taken);
3151 3162
3152 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3163 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3153 __ bind(&miss); 3164 __ bind(&miss);
3154 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); 3165 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
3155 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3166 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3156 3167
3157 // Return the generated code. 3168 // Return the generated code.
3158 return GetCode(CALLBACKS, name); 3169 return GetCode(CALLBACKS, name);
3159 } 3170 }
3160 3171
3161 3172
3162 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { 3173 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
3163 // ----------- S t a t e ------------- 3174 // ----------- S t a t e -------------
3164 // -- eax : key 3175 // -- eax : key
(...skipping 19 matching lines...) Expand all
3184 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3195 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3185 __ AssertFastElements(ecx); 3196 __ AssertFastElements(ecx);
3186 3197
3187 // Check that the key is within bounds. 3198 // Check that the key is within bounds.
3188 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 3199 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3189 __ j(above_equal, &miss, not_taken); 3200 __ j(above_equal, &miss, not_taken);
3190 3201
3191 // Load the result and make sure it's not the hole. 3202 // Load the result and make sure it's not the hole.
3192 __ mov(ebx, Operand(ecx, eax, times_2, 3203 __ mov(ebx, Operand(ecx, eax, times_2,
3193 FixedArray::kHeaderSize - kHeapObjectTag)); 3204 FixedArray::kHeaderSize - kHeapObjectTag));
3194 __ cmp(ebx, Factory::the_hole_value()); 3205 __ cmp(ebx, FACTORY->the_hole_value());
3195 __ j(equal, &miss, not_taken); 3206 __ j(equal, &miss, not_taken);
3196 __ mov(eax, ebx); 3207 __ mov(eax, ebx);
3197 __ ret(0); 3208 __ ret(0);
3198 3209
3199 __ bind(&miss); 3210 __ bind(&miss);
3200 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3211 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3201 3212
3202 // Return the generated code. 3213 // Return the generated code.
3203 return GetCode(NORMAL, NULL); 3214 return GetCode(NORMAL, NULL);
3204 } 3215 }
3205 3216
3206 3217
3207 // Specialized stub for constructing objects from functions which only have only 3218 // Specialized stub for constructing objects from functions which only have only
3208 // simple assignments of the form this.x = ...; in their body. 3219 // simple assignments of the form this.x = ...; in their body.
3209 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3220 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3210 // ----------- S t a t e ------------- 3221 // ----------- S t a t e -------------
3211 // -- eax : argc 3222 // -- eax : argc
3212 // -- edi : constructor 3223 // -- edi : constructor
3213 // -- esp[0] : return address 3224 // -- esp[0] : return address
3214 // -- esp[4] : last argument 3225 // -- esp[4] : last argument
3215 // ----------------------------------- 3226 // -----------------------------------
3216 Label generic_stub_call; 3227 Label generic_stub_call;
3217 #ifdef ENABLE_DEBUGGER_SUPPORT 3228 #ifdef ENABLE_DEBUGGER_SUPPORT
3218 // Check to see whether there are any break points in the function code. If 3229 // Check to see whether there are any break points in the function code. If
3219 // there are jump to the generic constructor stub which calls the actual 3230 // there are jump to the generic constructor stub which calls the actual
3220 // code for the function thereby hitting the break points. 3231 // code for the function thereby hitting the break points.
3221 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 3232 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
3222 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset)); 3233 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset));
3223 __ cmp(ebx, Factory::undefined_value()); 3234 __ cmp(ebx, FACTORY->undefined_value());
3224 __ j(not_equal, &generic_stub_call, not_taken); 3235 __ j(not_equal, &generic_stub_call, not_taken);
3225 #endif 3236 #endif
3226 3237
3227 // Load the initial map and verify that it is in fact a map. 3238 // Load the initial map and verify that it is in fact a map.
3228 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 3239 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
3229 // Will both indicate a NULL and a Smi. 3240 // Will both indicate a NULL and a Smi.
3230 __ test(ebx, Immediate(kSmiTagMask)); 3241 __ test(ebx, Immediate(kSmiTagMask));
3231 __ j(zero, &generic_stub_call); 3242 __ j(zero, &generic_stub_call);
3232 __ CmpObjectType(ebx, MAP_TYPE, ecx); 3243 __ CmpObjectType(ebx, MAP_TYPE, ecx);
3233 __ j(not_equal, &generic_stub_call); 3244 __ j(not_equal, &generic_stub_call);
(...skipping 16 matching lines...) Expand all
3250 edx, 3261 edx,
3251 ecx, 3262 ecx,
3252 no_reg, 3263 no_reg,
3253 &generic_stub_call, 3264 &generic_stub_call,
3254 NO_ALLOCATION_FLAGS); 3265 NO_ALLOCATION_FLAGS);
3255 3266
3256 // Allocated the JSObject, now initialize the fields and add the heap tag. 3267 // Allocated the JSObject, now initialize the fields and add the heap tag.
3257 // ebx: initial map 3268 // ebx: initial map
3258 // edx: JSObject (untagged) 3269 // edx: JSObject (untagged)
3259 __ mov(Operand(edx, JSObject::kMapOffset), ebx); 3270 __ mov(Operand(edx, JSObject::kMapOffset), ebx);
3260 __ mov(ebx, Factory::empty_fixed_array()); 3271 __ mov(ebx, FACTORY->empty_fixed_array());
3261 __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx); 3272 __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx);
3262 __ mov(Operand(edx, JSObject::kElementsOffset), ebx); 3273 __ mov(Operand(edx, JSObject::kElementsOffset), ebx);
3263 3274
3264 // Push the allocated object to the stack. This is the object that will be 3275 // Push the allocated object to the stack. This is the object that will be
3265 // returned (after it is tagged). 3276 // returned (after it is tagged).
3266 __ push(edx); 3277 __ push(edx);
3267 3278
3268 // eax: argc 3279 // eax: argc
3269 // edx: JSObject (untagged) 3280 // edx: JSObject (untagged)
3270 // Load the address of the first in-object property into edx. 3281 // Load the address of the first in-object property into edx.
3271 __ lea(edx, Operand(edx, JSObject::kHeaderSize)); 3282 __ lea(edx, Operand(edx, JSObject::kHeaderSize));
3272 // Calculate the location of the first argument. The stack contains the 3283 // Calculate the location of the first argument. The stack contains the
3273 // allocated object and the return address on top of the argc arguments. 3284 // allocated object and the return address on top of the argc arguments.
3274 __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize)); 3285 __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize));
3275 3286
3276 // Use edi for holding undefined which is used in several places below. 3287 // Use edi for holding undefined which is used in several places below.
3277 __ mov(edi, Factory::undefined_value()); 3288 __ mov(edi, FACTORY->undefined_value());
3278 3289
3279 // eax: argc 3290 // eax: argc
3280 // ecx: first argument 3291 // ecx: first argument
3281 // edx: first in-object property of the JSObject 3292 // edx: first in-object property of the JSObject
3282 // edi: undefined 3293 // edi: undefined
3283 // Fill the initialized properties with a constant value or a passed argument 3294 // Fill the initialized properties with a constant value or a passed argument
3284 // depending on the this.x = ...; assignment in the function. 3295 // depending on the this.x = ...; assignment in the function.
3285 SharedFunctionInfo* shared = function->shared(); 3296 SharedFunctionInfo* shared = function->shared();
3286 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3297 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3287 if (shared->IsThisPropertyAssignmentArgument(i)) { 3298 if (shared->IsThisPropertyAssignmentArgument(i)) {
3288 // Check if the argument assigned to the property is actually passed. 3299 // Check if the argument assigned to the property is actually passed.
3289 // If argument is not passed the property is set to undefined, 3300 // If argument is not passed the property is set to undefined,
3290 // otherwise find it on the stack. 3301 // otherwise find it on the stack.
3291 int arg_number = shared->GetThisPropertyAssignmentArgument(i); 3302 int arg_number = shared->GetThisPropertyAssignmentArgument(i);
3292 __ mov(ebx, edi); 3303 __ mov(ebx, edi);
3293 __ cmp(eax, arg_number); 3304 __ cmp(eax, arg_number);
3294 if (CpuFeatures::IsSupported(CMOV)) { 3305 if (Isolate::Current()->cpu_features()->IsSupported(CMOV)) {
3295 CpuFeatures::Scope use_cmov(CMOV); 3306 CpuFeatures::Scope use_cmov(CMOV);
3296 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); 3307 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
3297 } else { 3308 } else {
3298 Label not_passed; 3309 Label not_passed;
3299 __ j(below_equal, &not_passed); 3310 __ j(below_equal, &not_passed);
3300 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); 3311 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
3301 __ bind(&not_passed); 3312 __ bind(&not_passed);
3302 } 3313 }
3303 // Store value in the property. 3314 // Store value in the property.
3304 __ mov(Operand(edx, i * kPointerSize), ebx); 3315 __ mov(Operand(edx, i * kPointerSize), ebx);
(...skipping 14 matching lines...) Expand all
3319 3330
3320 // Move argc to ebx and retrieve and tag the JSObject to return. 3331 // Move argc to ebx and retrieve and tag the JSObject to return.
3321 __ mov(ebx, eax); 3332 __ mov(ebx, eax);
3322 __ pop(eax); 3333 __ pop(eax);
3323 __ or_(Operand(eax), Immediate(kHeapObjectTag)); 3334 __ or_(Operand(eax), Immediate(kHeapObjectTag));
3324 3335
3325 // Remove caller arguments and receiver from the stack and return. 3336 // Remove caller arguments and receiver from the stack and return.
3326 __ pop(ecx); 3337 __ pop(ecx);
3327 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); 3338 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
3328 __ push(ecx); 3339 __ push(ecx);
3329 __ IncrementCounter(&Counters::constructed_objects, 1); 3340 __ IncrementCounter(COUNTERS->constructed_objects(), 1);
3330 __ IncrementCounter(&Counters::constructed_objects_stub, 1); 3341 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
3331 __ ret(0); 3342 __ ret(0);
3332 3343
3333 // Jump to the generic stub in case the specialized code cannot handle the 3344 // Jump to the generic stub in case the specialized code cannot handle the
3334 // construction. 3345 // construction.
3335 __ bind(&generic_stub_call); 3346 __ bind(&generic_stub_call);
3336 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); 3347 Code* code = Isolate::Current()->builtins()->builtin(
3348 Builtins::JSConstructStubGeneric);
3337 Handle<Code> generic_construct_stub(code); 3349 Handle<Code> generic_construct_stub(code);
3338 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3350 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3339 3351
3340 // Return the generated code. 3352 // Return the generated code.
3341 return GetCode(); 3353 return GetCode();
3342 } 3354 }
3343 3355
3344 3356
3345 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3357 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3346 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3358 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3467 3479
3468 // If we fail allocation of the HeapNumber, we still have a value on 3480 // If we fail allocation of the HeapNumber, we still have a value on
3469 // top of the FPU stack. Remove it. 3481 // top of the FPU stack. Remove it.
3470 __ bind(&failed_allocation); 3482 __ bind(&failed_allocation);
3471 __ ffree(); 3483 __ ffree();
3472 __ fincstp(); 3484 __ fincstp();
3473 // Fall through to slow case. 3485 // Fall through to slow case.
3474 3486
3475 // Slow case: Jump to runtime. 3487 // Slow case: Jump to runtime.
3476 __ bind(&slow); 3488 __ bind(&slow);
3477 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); 3489 __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1);
3478 // ----------- S t a t e ------------- 3490 // ----------- S t a t e -------------
3479 // -- eax : key 3491 // -- eax : key
3480 // -- edx : receiver 3492 // -- edx : receiver
3481 // -- esp[0] : return address 3493 // -- esp[0] : return address
3482 // ----------------------------------- 3494 // -----------------------------------
3483 3495
3484 __ pop(ebx); 3496 __ pop(ebx);
3485 __ push(edx); // receiver 3497 __ push(edx); // receiver
3486 __ push(eax); // name 3498 __ push(eax); // name
3487 __ push(ebx); // return address 3499 __ push(ebx); // return address
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3580 3592
3581 // TODO(danno): handle heap number -> pixel array conversion 3593 // TODO(danno): handle heap number -> pixel array conversion
3582 if (array_type != kExternalPixelArray) { 3594 if (array_type != kExternalPixelArray) {
3583 __ bind(&check_heap_number); 3595 __ bind(&check_heap_number);
3584 // eax: value 3596 // eax: value
3585 // edx: receiver 3597 // edx: receiver
3586 // ecx: key 3598 // ecx: key
3587 // edi: elements array 3599 // edi: elements array
3588 // ebx: untagged index 3600 // ebx: untagged index
3589 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3601 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3590 Immediate(Factory::heap_number_map())); 3602 Immediate(FACTORY->heap_number_map()));
3591 __ j(not_equal, &slow); 3603 __ j(not_equal, &slow);
3592 3604
3593 // The WebGL specification leaves the behavior of storing NaN and 3605 // The WebGL specification leaves the behavior of storing NaN and
3594 // +/-Infinity into integer arrays basically undefined. For more 3606 // +/-Infinity into integer arrays basically undefined. For more
3595 // reproducible behavior, convert these to zero. 3607 // reproducible behavior, convert these to zero.
3596 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3608 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3597 // ebx: untagged index 3609 // ebx: untagged index
3598 // edi: base pointer of external storage 3610 // edi: base pointer of external storage
3599 if (array_type == kExternalFloatArray) { 3611 if (array_type == kExternalFloatArray) {
3600 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3612 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3601 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3613 __ fstp_s(Operand(edi, ebx, times_4, 0));
3602 __ ret(0); 3614 __ ret(0);
3603 } else { 3615 } else {
3604 // Perform float-to-int conversion with truncation (round-to-zero) 3616 // Perform float-to-int conversion with truncation (round-to-zero)
3605 // behavior. 3617 // behavior.
3606 3618
3607 // For the moment we make the slow call to the runtime on 3619 // For the moment we make the slow call to the runtime on
3608 // processors that don't support SSE2. The code in IntegerConvert 3620 // processors that don't support SSE2. The code in IntegerConvert
3609 // (code-stubs-ia32.cc) is roughly what is needed here though the 3621 // (code-stubs-ia32.cc) is roughly what is needed here though the
3610 // conversion failure case does not need to be handled. 3622 // conversion failure case does not need to be handled.
3611 if (CpuFeatures::IsSupported(SSE2)) { 3623 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) {
3612 if (array_type != kExternalIntArray && 3624 if (array_type != kExternalIntArray &&
3613 array_type != kExternalUnsignedIntArray) { 3625 array_type != kExternalUnsignedIntArray) {
3614 ASSERT(CpuFeatures::IsSupported(SSE2)); 3626 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3615 CpuFeatures::Scope scope(SSE2); 3627 CpuFeatures::Scope scope(SSE2);
3616 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); 3628 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3617 // ecx: untagged integer value 3629 // ecx: untagged integer value
3618 switch (array_type) { 3630 switch (array_type) {
3619 case kExternalPixelArray: 3631 case kExternalPixelArray:
3620 { // Clamp the value to [0..255]. 3632 { // Clamp the value to [0..255].
3621 NearLabel done; 3633 NearLabel done;
3622 __ test(ecx, Immediate(0xFFFFFF00)); 3634 __ test(ecx, Immediate(0xFFFFFF00));
3623 __ j(zero, &done); 3635 __ j(zero, &done);
3624 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3636 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3625 __ dec_b(ecx); // 0 if negative, 255 if positive. 3637 __ dec_b(ecx); // 0 if negative, 255 if positive.
3626 __ bind(&done); 3638 __ bind(&done);
3627 } 3639 }
3628 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3640 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3629 case kExternalByteArray: 3641 case kExternalByteArray:
3630 case kExternalUnsignedByteArray: 3642 case kExternalUnsignedByteArray:
3631 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3643 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3632 break; 3644 break;
3633 case kExternalShortArray: 3645 case kExternalShortArray:
3634 case kExternalUnsignedShortArray: 3646 case kExternalUnsignedShortArray:
3635 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3647 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3636 break; 3648 break;
3637 default: 3649 default:
3638 UNREACHABLE(); 3650 UNREACHABLE();
3639 break; 3651 break;
3640 } 3652 }
3641 } else { 3653 } else {
3642 if (CpuFeatures::IsSupported(SSE3)) { 3654 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) {
3643 CpuFeatures::Scope scope(SSE3); 3655 CpuFeatures::Scope scope(SSE3);
3644 // fisttp stores values as signed integers. To represent the 3656 // fisttp stores values as signed integers. To represent the
3645 // entire range of int and unsigned int arrays, store as a 3657 // entire range of int and unsigned int arrays, store as a
3646 // 64-bit int and discard the high 32 bits. 3658 // 64-bit int and discard the high 32 bits.
3647 // If the value is NaN or +/-infinity, the result is 0x80000000, 3659 // If the value is NaN or +/-infinity, the result is 0x80000000,
3648 // which is automatically zero when taken mod 2^n, n < 32. 3660 // which is automatically zero when taken mod 2^n, n < 32.
3649 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3661 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3650 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3662 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3651 __ fisttp_d(Operand(esp, 0)); 3663 __ fisttp_d(Operand(esp, 0));
3652 __ pop(ecx); 3664 __ pop(ecx);
3653 __ add(Operand(esp), Immediate(kPointerSize)); 3665 __ add(Operand(esp), Immediate(kPointerSize));
3654 } else { 3666 } else {
3655 ASSERT(CpuFeatures::IsSupported(SSE2)); 3667 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3656 CpuFeatures::Scope scope(SSE2); 3668 CpuFeatures::Scope scope(SSE2);
3657 // We can easily implement the correct rounding behavior for the 3669 // We can easily implement the correct rounding behavior for the
3658 // range [0, 2^31-1]. For the time being, to keep this code simple, 3670 // range [0, 2^31-1]. For the time being, to keep this code simple,
3659 // make the slow runtime call for values outside this range. 3671 // make the slow runtime call for values outside this range.
3660 // Note: we could do better for signed int arrays. 3672 // Note: we could do better for signed int arrays.
3661 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3673 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3662 // We will need the key if we have to make the slow runtime call. 3674 // We will need the key if we have to make the slow runtime call.
3663 __ push(ecx); 3675 __ push(ecx);
3664 __ LoadPowerOf2(xmm1, ecx, 31); 3676 __ LoadPowerOf2(xmm1, ecx, 31);
3665 __ pop(ecx); 3677 __ pop(ecx);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3698 3710
3699 return GetCode(flags); 3711 return GetCode(flags);
3700 } 3712 }
3701 3713
3702 3714
3703 #undef __ 3715 #undef __
3704 3716
3705 } } // namespace v8::internal 3717 } } // namespace v8::internal
3706 3718
3707 #endif // V8_TARGET_ARCH_IA32 3719 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698