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

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

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/simulator-ia32.h ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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, with_write_barrier, attempt_to_grow_elements; 1470 Label exit, with_write_barrier, attempt_to_grow_elements;
1467 1471
1468 // Get the array's length into eax and calculate new length. 1472 // Get the array's length into eax and calculate new length.
1469 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1473 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1470 STATIC_ASSERT(kSmiTagSize == 1); 1474 STATIC_ASSERT(kSmiTagSize == 1);
1471 STATIC_ASSERT(kSmiTag == 0); 1475 STATIC_ASSERT(kSmiTag == 0);
1472 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); 1476 __ add(Operand(eax), Immediate(Smi::FromInt(argc)));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 1532
1529 // We fit and could grow elements. 1533 // We fit and could grow elements.
1530 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); 1534 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
1531 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1535 __ mov(ecx, Operand(esp, argc * kPointerSize));
1532 1536
1533 // Push the argument... 1537 // Push the argument...
1534 __ mov(Operand(edx, 0), ecx); 1538 __ mov(Operand(edx, 0), ecx);
1535 // ... and fill the rest with holes. 1539 // ... and fill the rest with holes.
1536 for (int i = 1; i < kAllocationDelta; i++) { 1540 for (int i = 1; i < kAllocationDelta; i++) {
1537 __ mov(Operand(edx, i * kPointerSize), 1541 __ mov(Operand(edx, i * kPointerSize),
1538 Immediate(Factory::the_hole_value())); 1542 Immediate(FACTORY->the_hole_value()));
1539 } 1543 }
1540 1544
1541 // Restore receiver to edx as finish sequence assumes it's here. 1545 // Restore receiver to edx as finish sequence assumes it's here.
1542 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1546 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1543 1547
1544 // Increment element's and array's sizes. 1548 // Increment element's and array's sizes.
1545 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), 1549 __ add(FieldOperand(ebx, FixedArray::kLengthOffset),
1546 Immediate(Smi::FromInt(kAllocationDelta))); 1550 Immediate(Smi::FromInt(kAllocationDelta)));
1547 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1551 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1548 1552
(...skipping 25 matching lines...) Expand all
1574 String* name) { 1578 String* name) {
1575 // ----------- S t a t e ------------- 1579 // ----------- S t a t e -------------
1576 // -- ecx : name 1580 // -- ecx : name
1577 // -- esp[0] : return address 1581 // -- esp[0] : return address
1578 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1582 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1579 // -- ... 1583 // -- ...
1580 // -- esp[(argc + 1) * 4] : receiver 1584 // -- esp[(argc + 1) * 4] : receiver
1581 // ----------------------------------- 1585 // -----------------------------------
1582 1586
1583 // If object is not an array, bail out to regular call. 1587 // If object is not an array, bail out to regular call.
1584 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); 1588 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
1585 1589
1586 Label miss, return_undefined, call_builtin; 1590 Label miss, return_undefined, call_builtin;
1587 1591
1588 GenerateNameCheck(name, &miss); 1592 GenerateNameCheck(name, &miss);
1589 1593
1590 // Get the receiver from the stack. 1594 // Get the receiver from the stack.
1591 const int argc = arguments().immediate(); 1595 const int argc = arguments().immediate();
1592 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1596 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1593 1597
1594 // Check that the receiver isn't a smi. 1598 // Check that the receiver isn't a smi.
1595 __ test(edx, Immediate(kSmiTagMask)); 1599 __ test(edx, Immediate(kSmiTagMask));
1596 __ j(zero, &miss); 1600 __ j(zero, &miss);
1597 CheckPrototypes(JSObject::cast(object), edx, 1601 CheckPrototypes(JSObject::cast(object), edx,
1598 holder, ebx, 1602 holder, ebx,
1599 eax, edi, name, &miss); 1603 eax, edi, name, &miss);
1600 1604
1601 // Get the elements array of the object. 1605 // Get the elements array of the object.
1602 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1606 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1603 1607
1604 // Check that the elements are in fast mode and writable. 1608 // Check that the elements are in fast mode and writable.
1605 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1609 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1606 Immediate(Factory::fixed_array_map())); 1610 Immediate(FACTORY->fixed_array_map()));
1607 __ j(not_equal, &call_builtin); 1611 __ j(not_equal, &call_builtin);
1608 1612
1609 // Get the array's length into ecx and calculate new length. 1613 // Get the array's length into ecx and calculate new length.
1610 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); 1614 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset));
1611 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); 1615 __ sub(Operand(ecx), Immediate(Smi::FromInt(1)));
1612 __ j(negative, &return_undefined); 1616 __ j(negative, &return_undefined);
1613 1617
1614 // Get the last element. 1618 // Get the last element.
1615 STATIC_ASSERT(kSmiTagSize == 1); 1619 STATIC_ASSERT(kSmiTagSize == 1);
1616 STATIC_ASSERT(kSmiTag == 0); 1620 STATIC_ASSERT(kSmiTag == 0);
1617 __ mov(eax, FieldOperand(ebx, 1621 __ mov(eax, FieldOperand(ebx,
1618 ecx, times_half_pointer_size, 1622 ecx, times_half_pointer_size,
1619 FixedArray::kHeaderSize)); 1623 FixedArray::kHeaderSize));
1620 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); 1624 __ cmp(Operand(eax), Immediate(FACTORY->the_hole_value()));
1621 __ j(equal, &call_builtin); 1625 __ j(equal, &call_builtin);
1622 1626
1623 // Set the array's length. 1627 // Set the array's length.
1624 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); 1628 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
1625 1629
1626 // Fill with the hole. 1630 // Fill with the hole.
1627 __ mov(FieldOperand(ebx, 1631 __ mov(FieldOperand(ebx,
1628 ecx, times_half_pointer_size, 1632 ecx, times_half_pointer_size,
1629 FixedArray::kHeaderSize), 1633 FixedArray::kHeaderSize),
1630 Immediate(Factory::the_hole_value())); 1634 Immediate(FACTORY->the_hole_value()));
1631 __ ret((argc + 1) * kPointerSize); 1635 __ ret((argc + 1) * kPointerSize);
1632 1636
1633 __ bind(&return_undefined); 1637 __ bind(&return_undefined);
1634 __ mov(eax, Immediate(Factory::undefined_value())); 1638 __ mov(eax, Immediate(FACTORY->undefined_value()));
1635 __ ret((argc + 1) * kPointerSize); 1639 __ ret((argc + 1) * kPointerSize);
1636 1640
1637 __ bind(&call_builtin); 1641 __ bind(&call_builtin);
1638 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), 1642 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop),
1639 argc + 1, 1643 argc + 1,
1640 1); 1644 1);
1641 1645
1642 __ bind(&miss); 1646 __ bind(&miss);
1643 Object* obj; 1647 Object* obj;
1644 { MaybeObject* maybe_obj = GenerateMissBranch(); 1648 { MaybeObject* maybe_obj = GenerateMissBranch();
(...skipping 13 matching lines...) Expand all
1658 String* name) { 1662 String* name) {
1659 // ----------- S t a t e ------------- 1663 // ----------- S t a t e -------------
1660 // -- ecx : function name 1664 // -- ecx : function name
1661 // -- esp[0] : return address 1665 // -- esp[0] : return address
1662 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1666 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1663 // -- ... 1667 // -- ...
1664 // -- esp[(argc + 1) * 4] : receiver 1668 // -- esp[(argc + 1) * 4] : receiver
1665 // ----------------------------------- 1669 // -----------------------------------
1666 1670
1667 // If object is not a string, bail out to regular call. 1671 // If object is not a string, bail out to regular call.
1668 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); 1672 if (!object->IsString() || cell != NULL) return HEAP->undefined_value();
1669 1673
1670 const int argc = arguments().immediate(); 1674 const int argc = arguments().immediate();
1671 1675
1672 Label miss; 1676 Label miss;
1673 Label name_miss; 1677 Label name_miss;
1674 Label index_out_of_range; 1678 Label index_out_of_range;
1675 Label* index_out_of_range_label = &index_out_of_range; 1679 Label* index_out_of_range_label = &index_out_of_range;
1676 1680
1677 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1681 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
1678 index_out_of_range_label = &miss; 1682 index_out_of_range_label = &miss;
(...skipping 11 matching lines...) Expand all
1690 ebx, edx, edi, name, &miss); 1694 ebx, edx, edi, name, &miss);
1691 1695
1692 Register receiver = ebx; 1696 Register receiver = ebx;
1693 Register index = edi; 1697 Register index = edi;
1694 Register scratch = edx; 1698 Register scratch = edx;
1695 Register result = eax; 1699 Register result = eax;
1696 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 1700 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
1697 if (argc > 0) { 1701 if (argc > 0) {
1698 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 1702 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
1699 } else { 1703 } else {
1700 __ Set(index, Immediate(Factory::undefined_value())); 1704 __ Set(index, Immediate(FACTORY->undefined_value()));
1701 } 1705 }
1702 1706
1703 StringCharCodeAtGenerator char_code_at_generator(receiver, 1707 StringCharCodeAtGenerator char_code_at_generator(receiver,
1704 index, 1708 index,
1705 scratch, 1709 scratch,
1706 result, 1710 result,
1707 &miss, // When not a string. 1711 &miss, // When not a string.
1708 &miss, // When not a number. 1712 &miss, // When not a number.
1709 index_out_of_range_label, 1713 index_out_of_range_label,
1710 STRING_INDEX_IS_NUMBER); 1714 STRING_INDEX_IS_NUMBER);
1711 char_code_at_generator.GenerateFast(masm()); 1715 char_code_at_generator.GenerateFast(masm());
1712 __ ret((argc + 1) * kPointerSize); 1716 __ ret((argc + 1) * kPointerSize);
1713 1717
1714 StubRuntimeCallHelper call_helper; 1718 StubRuntimeCallHelper call_helper;
1715 char_code_at_generator.GenerateSlow(masm(), call_helper); 1719 char_code_at_generator.GenerateSlow(masm(), call_helper);
1716 1720
1717 if (index_out_of_range.is_linked()) { 1721 if (index_out_of_range.is_linked()) {
1718 __ bind(&index_out_of_range); 1722 __ bind(&index_out_of_range);
1719 __ Set(eax, Immediate(Factory::nan_value())); 1723 __ Set(eax, Immediate(FACTORY->nan_value()));
1720 __ ret((argc + 1) * kPointerSize); 1724 __ ret((argc + 1) * kPointerSize);
1721 } 1725 }
1722 1726
1723 __ bind(&miss); 1727 __ bind(&miss);
1724 // Restore function name in ecx. 1728 // Restore function name in ecx.
1725 __ Set(ecx, Immediate(Handle<String>(name))); 1729 __ Set(ecx, Immediate(Handle<String>(name)));
1726 __ bind(&name_miss); 1730 __ bind(&name_miss);
1727 Object* obj; 1731 Object* obj;
1728 { MaybeObject* maybe_obj = GenerateMissBranch(); 1732 { MaybeObject* maybe_obj = GenerateMissBranch();
1729 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1733 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 12 matching lines...) Expand all
1742 String* name) { 1746 String* name) {
1743 // ----------- S t a t e ------------- 1747 // ----------- S t a t e -------------
1744 // -- ecx : function name 1748 // -- ecx : function name
1745 // -- esp[0] : return address 1749 // -- esp[0] : return address
1746 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1750 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1747 // -- ... 1751 // -- ...
1748 // -- esp[(argc + 1) * 4] : receiver 1752 // -- esp[(argc + 1) * 4] : receiver
1749 // ----------------------------------- 1753 // -----------------------------------
1750 1754
1751 // If object is not a string, bail out to regular call. 1755 // If object is not a string, bail out to regular call.
1752 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); 1756 if (!object->IsString() || cell != NULL) return HEAP->undefined_value();
1753 1757
1754 const int argc = arguments().immediate(); 1758 const int argc = arguments().immediate();
1755 1759
1756 Label miss; 1760 Label miss;
1757 Label name_miss; 1761 Label name_miss;
1758 Label index_out_of_range; 1762 Label index_out_of_range;
1759 Label* index_out_of_range_label = &index_out_of_range; 1763 Label* index_out_of_range_label = &index_out_of_range;
1760 1764
1761 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1765 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
1762 index_out_of_range_label = &miss; 1766 index_out_of_range_label = &miss;
(...skipping 12 matching lines...) Expand all
1775 1779
1776 Register receiver = eax; 1780 Register receiver = eax;
1777 Register index = edi; 1781 Register index = edi;
1778 Register scratch1 = ebx; 1782 Register scratch1 = ebx;
1779 Register scratch2 = edx; 1783 Register scratch2 = edx;
1780 Register result = eax; 1784 Register result = eax;
1781 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 1785 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
1782 if (argc > 0) { 1786 if (argc > 0) {
1783 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 1787 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
1784 } else { 1788 } else {
1785 __ Set(index, Immediate(Factory::undefined_value())); 1789 __ Set(index, Immediate(FACTORY->undefined_value()));
1786 } 1790 }
1787 1791
1788 StringCharAtGenerator char_at_generator(receiver, 1792 StringCharAtGenerator char_at_generator(receiver,
1789 index, 1793 index,
1790 scratch1, 1794 scratch1,
1791 scratch2, 1795 scratch2,
1792 result, 1796 result,
1793 &miss, // When not a string. 1797 &miss, // When not a string.
1794 &miss, // When not a number. 1798 &miss, // When not a number.
1795 index_out_of_range_label, 1799 index_out_of_range_label,
1796 STRING_INDEX_IS_NUMBER); 1800 STRING_INDEX_IS_NUMBER);
1797 char_at_generator.GenerateFast(masm()); 1801 char_at_generator.GenerateFast(masm());
1798 __ ret((argc + 1) * kPointerSize); 1802 __ ret((argc + 1) * kPointerSize);
1799 1803
1800 StubRuntimeCallHelper call_helper; 1804 StubRuntimeCallHelper call_helper;
1801 char_at_generator.GenerateSlow(masm(), call_helper); 1805 char_at_generator.GenerateSlow(masm(), call_helper);
1802 1806
1803 if (index_out_of_range.is_linked()) { 1807 if (index_out_of_range.is_linked()) {
1804 __ bind(&index_out_of_range); 1808 __ bind(&index_out_of_range);
1805 __ Set(eax, Immediate(Factory::empty_string())); 1809 __ Set(eax, Immediate(FACTORY->empty_string()));
1806 __ ret((argc + 1) * kPointerSize); 1810 __ ret((argc + 1) * kPointerSize);
1807 } 1811 }
1808 1812
1809 __ bind(&miss); 1813 __ bind(&miss);
1810 // Restore function name in ecx. 1814 // Restore function name in ecx.
1811 __ Set(ecx, Immediate(Handle<String>(name))); 1815 __ Set(ecx, Immediate(Handle<String>(name)));
1812 __ bind(&name_miss); 1816 __ bind(&name_miss);
1813 Object* obj; 1817 Object* obj;
1814 { MaybeObject* maybe_obj = GenerateMissBranch(); 1818 { MaybeObject* maybe_obj = GenerateMissBranch();
1815 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1819 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 15 matching lines...) Expand all
1831 // -- esp[0] : return address 1835 // -- esp[0] : return address
1832 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1836 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1833 // -- ... 1837 // -- ...
1834 // -- esp[(argc + 1) * 4] : receiver 1838 // -- esp[(argc + 1) * 4] : receiver
1835 // ----------------------------------- 1839 // -----------------------------------
1836 1840
1837 const int argc = arguments().immediate(); 1841 const int argc = arguments().immediate();
1838 1842
1839 // If the object is not a JSObject or we got an unexpected number of 1843 // If the object is not a JSObject or we got an unexpected number of
1840 // arguments, bail out to the regular call. 1844 // arguments, bail out to the regular call.
1841 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); 1845 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
1842 1846
1843 Label miss; 1847 Label miss;
1844 GenerateNameCheck(name, &miss); 1848 GenerateNameCheck(name, &miss);
1845 1849
1846 if (cell == NULL) { 1850 if (cell == NULL) {
1847 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1851 __ mov(edx, Operand(esp, 2 * kPointerSize));
1848 1852
1849 STATIC_ASSERT(kSmiTag == 0); 1853 STATIC_ASSERT(kSmiTag == 0);
1850 __ test(edx, Immediate(kSmiTagMask)); 1854 __ test(edx, Immediate(kSmiTagMask));
1851 __ j(zero, &miss); 1855 __ j(zero, &miss);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 JSFunction* function, 1905 JSFunction* function,
1902 String* name) { 1906 String* name) {
1903 // ----------- S t a t e ------------- 1907 // ----------- S t a t e -------------
1904 // -- ecx : name 1908 // -- ecx : name
1905 // -- esp[0] : return address 1909 // -- esp[0] : return address
1906 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1910 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1907 // -- ... 1911 // -- ...
1908 // -- esp[(argc + 1) * 4] : receiver 1912 // -- esp[(argc + 1) * 4] : receiver
1909 // ----------------------------------- 1913 // -----------------------------------
1910 1914
1911 if (!CpuFeatures::IsSupported(SSE2)) return Heap::undefined_value(); 1915 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2))
1916 return HEAP->undefined_value();
1912 CpuFeatures::Scope use_sse2(SSE2); 1917 CpuFeatures::Scope use_sse2(SSE2);
1913 1918
1914 const int argc = arguments().immediate(); 1919 const int argc = arguments().immediate();
1915 1920
1916 // If the object is not a JSObject or we got an unexpected number of 1921 // If the object is not a JSObject or we got an unexpected number of
1917 // arguments, bail out to the regular call. 1922 // arguments, bail out to the regular call.
1918 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); 1923 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
1919 1924
1920 Label miss; 1925 Label miss;
1921 GenerateNameCheck(name, &miss); 1926 GenerateNameCheck(name, &miss);
1922 1927
1923 if (cell == NULL) { 1928 if (cell == NULL) {
1924 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1929 __ mov(edx, Operand(esp, 2 * kPointerSize));
1925 1930
1926 STATIC_ASSERT(kSmiTag == 0); 1931 STATIC_ASSERT(kSmiTag == 0);
1927 __ test(edx, Immediate(kSmiTagMask)); 1932 __ test(edx, Immediate(kSmiTagMask));
1928 __ j(zero, &miss); 1933 __ j(zero, &miss);
(...skipping 10 matching lines...) Expand all
1939 __ mov(eax, Operand(esp, 1 * kPointerSize)); 1944 __ mov(eax, Operand(esp, 1 * kPointerSize));
1940 1945
1941 // Check if the argument is a smi. 1946 // Check if the argument is a smi.
1942 Label smi; 1947 Label smi;
1943 STATIC_ASSERT(kSmiTag == 0); 1948 STATIC_ASSERT(kSmiTag == 0);
1944 __ test(eax, Immediate(kSmiTagMask)); 1949 __ test(eax, Immediate(kSmiTagMask));
1945 __ j(zero, &smi); 1950 __ j(zero, &smi);
1946 1951
1947 // Check if the argument is a heap number and load its value into xmm0. 1952 // Check if the argument is a heap number and load its value into xmm0.
1948 Label slow; 1953 Label slow;
1949 __ CheckMap(eax, Factory::heap_number_map(), &slow, true); 1954 __ CheckMap(eax, FACTORY->heap_number_map(), &slow, true);
1950 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 1955 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
1951 1956
1952 // Check if the argument is strictly positive. Note this also 1957 // Check if the argument is strictly positive. Note this also
1953 // discards NaN. 1958 // discards NaN.
1954 __ xorpd(xmm1, xmm1); 1959 __ xorpd(xmm1, xmm1);
1955 __ ucomisd(xmm0, xmm1); 1960 __ ucomisd(xmm0, xmm1);
1956 __ j(below_equal, &slow); 1961 __ j(below_equal, &slow);
1957 1962
1958 // Do a truncating conversion. 1963 // Do a truncating conversion.
1959 __ cvttsd2si(eax, Operand(xmm0)); 1964 __ cvttsd2si(eax, Operand(xmm0));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 // -- esp[0] : return address 2037 // -- esp[0] : return address
2033 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2038 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2034 // -- ... 2039 // -- ...
2035 // -- esp[(argc + 1) * 4] : receiver 2040 // -- esp[(argc + 1) * 4] : receiver
2036 // ----------------------------------- 2041 // -----------------------------------
2037 2042
2038 const int argc = arguments().immediate(); 2043 const int argc = arguments().immediate();
2039 2044
2040 // If the object is not a JSObject or we got an unexpected number of 2045 // If the object is not a JSObject or we got an unexpected number of
2041 // arguments, bail out to the regular call. 2046 // arguments, bail out to the regular call.
2042 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); 2047 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
2043 2048
2044 Label miss; 2049 Label miss;
2045 GenerateNameCheck(name, &miss); 2050 GenerateNameCheck(name, &miss);
2046 2051
2047 if (cell == NULL) { 2052 if (cell == NULL) {
2048 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2053 __ mov(edx, Operand(esp, 2 * kPointerSize));
2049 2054
2050 STATIC_ASSERT(kSmiTag == 0); 2055 STATIC_ASSERT(kSmiTag == 0);
2051 __ test(edx, Immediate(kSmiTagMask)); 2056 __ test(edx, Immediate(kSmiTagMask));
2052 __ j(zero, &miss); 2057 __ j(zero, &miss);
(...skipping 30 matching lines...) Expand all
2083 // This only happens for the most negative smi. 2088 // This only happens for the most negative smi.
2084 Label slow; 2089 Label slow;
2085 __ j(negative, &slow); 2090 __ j(negative, &slow);
2086 2091
2087 // Smi case done. 2092 // Smi case done.
2088 __ ret(2 * kPointerSize); 2093 __ ret(2 * kPointerSize);
2089 2094
2090 // Check if the argument is a heap number and load its exponent and 2095 // Check if the argument is a heap number and load its exponent and
2091 // sign into ebx. 2096 // sign into ebx.
2092 __ bind(&not_smi); 2097 __ bind(&not_smi);
2093 __ CheckMap(eax, Factory::heap_number_map(), &slow, true); 2098 __ CheckMap(eax, FACTORY->heap_number_map(), &slow, true);
2094 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset)); 2099 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset));
2095 2100
2096 // Check the sign of the argument. If the argument is positive, 2101 // Check the sign of the argument. If the argument is positive,
2097 // just return it. 2102 // just return it.
2098 Label negative_sign; 2103 Label negative_sign;
2099 __ test(ebx, Immediate(HeapNumber::kSignMask)); 2104 __ test(ebx, Immediate(HeapNumber::kSignMask));
2100 __ j(not_zero, &negative_sign); 2105 __ j(not_zero, &negative_sign);
2101 __ ret(2 * kPointerSize); 2106 __ ret(2 * kPointerSize);
2102 2107
2103 // If the argument is negative, clear the sign, and return a new 2108 // If the argument is negative, clear the sign, and return a new
(...skipping 26 matching lines...) Expand all
2130 MaybeObject* CallStubCompiler::CompileFastApiCall( 2135 MaybeObject* CallStubCompiler::CompileFastApiCall(
2131 const CallOptimization& optimization, 2136 const CallOptimization& optimization,
2132 Object* object, 2137 Object* object,
2133 JSObject* holder, 2138 JSObject* holder,
2134 JSGlobalPropertyCell* cell, 2139 JSGlobalPropertyCell* cell,
2135 JSFunction* function, 2140 JSFunction* function,
2136 String* name) { 2141 String* name) {
2137 ASSERT(optimization.is_simple_api_call()); 2142 ASSERT(optimization.is_simple_api_call());
2138 // Bail out if object is a global object as we don't want to 2143 // Bail out if object is a global object as we don't want to
2139 // repatch it to global receiver. 2144 // repatch it to global receiver.
2140 if (object->IsGlobalObject()) return Heap::undefined_value(); 2145 if (object->IsGlobalObject()) return HEAP->undefined_value();
2141 if (cell != NULL) return Heap::undefined_value(); 2146 if (cell != NULL) return HEAP->undefined_value();
2142 int depth = optimization.GetPrototypeDepthOfExpectedType( 2147 int depth = optimization.GetPrototypeDepthOfExpectedType(
2143 JSObject::cast(object), holder); 2148 JSObject::cast(object), holder);
2144 if (depth == kInvalidProtoDepth) return Heap::undefined_value(); 2149 if (depth == kInvalidProtoDepth) return HEAP->undefined_value();
2145 2150
2146 Label miss, miss_before_stack_reserved; 2151 Label miss, miss_before_stack_reserved;
2147 2152
2148 GenerateNameCheck(name, &miss_before_stack_reserved); 2153 GenerateNameCheck(name, &miss_before_stack_reserved);
2149 2154
2150 // Get the receiver from the stack. 2155 // Get the receiver from the stack.
2151 const int argc = arguments().immediate(); 2156 const int argc = arguments().immediate();
2152 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2157 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2153 2158
2154 // Check that the receiver isn't a smi. 2159 // Check that the receiver isn't a smi.
2155 __ test(edx, Immediate(kSmiTagMask)); 2160 __ test(edx, Immediate(kSmiTagMask));
2156 __ j(zero, &miss_before_stack_reserved, not_taken); 2161 __ j(zero, &miss_before_stack_reserved, not_taken);
2157 2162
2158 __ IncrementCounter(&Counters::call_const, 1); 2163 __ IncrementCounter(COUNTERS->call_const(), 1);
2159 __ IncrementCounter(&Counters::call_const_fast_api, 1); 2164 __ IncrementCounter(COUNTERS->call_const_fast_api(), 1);
2160 2165
2161 // Allocate space for v8::Arguments implicit values. Must be initialized 2166 // Allocate space for v8::Arguments implicit values. Must be initialized
2162 // before calling any runtime function. 2167 // before calling any runtime function.
2163 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); 2168 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2164 2169
2165 // Check that the maps haven't changed and find a Holder as a side effect. 2170 // Check that the maps haven't changed and find a Holder as a side effect.
2166 CheckPrototypes(JSObject::cast(object), edx, holder, 2171 CheckPrototypes(JSObject::cast(object), edx, holder,
2167 ebx, eax, edi, name, depth, &miss); 2172 ebx, eax, edi, name, depth, &miss);
2168 2173
2169 // Move the return address on top of the stack. 2174 // Move the return address on top of the stack.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 __ j(zero, &miss, not_taken); 2230 __ j(zero, &miss, not_taken);
2226 } 2231 }
2227 2232
2228 // Make sure that it's okay not to patch the on stack receiver 2233 // Make sure that it's okay not to patch the on stack receiver
2229 // unless we're doing a receiver map check. 2234 // unless we're doing a receiver map check.
2230 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2235 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2231 2236
2232 SharedFunctionInfo* function_info = function->shared(); 2237 SharedFunctionInfo* function_info = function->shared();
2233 switch (check) { 2238 switch (check) {
2234 case RECEIVER_MAP_CHECK: 2239 case RECEIVER_MAP_CHECK:
2235 __ IncrementCounter(&Counters::call_const, 1); 2240 __ IncrementCounter(COUNTERS->call_const(), 1);
2236 2241
2237 // Check that the maps haven't changed. 2242 // Check that the maps haven't changed.
2238 CheckPrototypes(JSObject::cast(object), edx, holder, 2243 CheckPrototypes(JSObject::cast(object), edx, holder,
2239 ebx, eax, edi, name, &miss); 2244 ebx, eax, edi, name, &miss);
2240 2245
2241 // Patch the receiver on the stack with the global proxy if 2246 // Patch the receiver on the stack with the global proxy if
2242 // necessary. 2247 // necessary.
2243 if (object->IsGlobalObject()) { 2248 if (object->IsGlobalObject()) {
2244 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2249 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2245 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2250 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 } 2291 }
2287 2292
2288 case BOOLEAN_CHECK: { 2293 case BOOLEAN_CHECK: {
2289 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2294 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2290 // Calling non-strict non-builtins with a value as the receiver 2295 // Calling non-strict non-builtins with a value as the receiver
2291 // requires boxing. 2296 // requires boxing.
2292 __ jmp(&miss); 2297 __ jmp(&miss);
2293 } else { 2298 } else {
2294 Label fast; 2299 Label fast;
2295 // Check that the object is a boolean. 2300 // Check that the object is a boolean.
2296 __ cmp(edx, Factory::true_value()); 2301 __ cmp(edx, FACTORY->true_value());
2297 __ j(equal, &fast, taken); 2302 __ j(equal, &fast, taken);
2298 __ cmp(edx, Factory::false_value()); 2303 __ cmp(edx, FACTORY->false_value());
2299 __ j(not_equal, &miss, not_taken); 2304 __ j(not_equal, &miss, not_taken);
2300 __ bind(&fast); 2305 __ bind(&fast);
2301 // Check that the maps starting from the prototype haven't changed. 2306 // Check that the maps starting from the prototype haven't changed.
2302 GenerateDirectLoadGlobalFunctionPrototype( 2307 GenerateDirectLoadGlobalFunctionPrototype(
2303 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2308 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
2304 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2309 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
2305 ebx, edx, edi, name, &miss); 2310 ebx, edx, edi, name, &miss);
2306 } 2311 }
2307 break; 2312 break;
2308 } 2313 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 // Patch the receiver on the stack with the global proxy. 2434 // Patch the receiver on the stack with the global proxy.
2430 if (object->IsGlobalObject()) { 2435 if (object->IsGlobalObject()) {
2431 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2436 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2432 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2437 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2433 } 2438 }
2434 2439
2435 // Setup the context (function already in edi). 2440 // Setup the context (function already in edi).
2436 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2441 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2437 2442
2438 // Jump to the cached code (tail call). 2443 // Jump to the cached code (tail call).
2439 __ IncrementCounter(&Counters::call_global_inline, 1); 2444 __ IncrementCounter(COUNTERS->call_global_inline(), 1);
2440 ASSERT(function->is_compiled()); 2445 ASSERT(function->is_compiled());
2441 ParameterCount expected(function->shared()->formal_parameter_count()); 2446 ParameterCount expected(function->shared()->formal_parameter_count());
2442 if (V8::UseCrankshaft()) { 2447 if (V8::UseCrankshaft()) {
2443 // TODO(kasperl): For now, we always call indirectly through the 2448 // TODO(kasperl): For now, we always call indirectly through the
2444 // code field in the function to allow recompilation to take effect 2449 // code field in the function to allow recompilation to take effect
2445 // without changing any of the call sites. 2450 // without changing any of the call sites.
2446 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2451 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2447 expected, arguments(), JUMP_FUNCTION); 2452 expected, arguments(), JUMP_FUNCTION);
2448 } else { 2453 } else {
2449 Handle<Code> code(function->code()); 2454 Handle<Code> code(function->code());
2450 __ InvokeCode(code, expected, arguments(), 2455 __ InvokeCode(code, expected, arguments(),
2451 RelocInfo::CODE_TARGET, JUMP_FUNCTION); 2456 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
2452 } 2457 }
2453 2458
2454 // Handle call cache miss. 2459 // Handle call cache miss.
2455 __ bind(&miss); 2460 __ bind(&miss);
2456 __ IncrementCounter(&Counters::call_global_inline_miss, 1); 2461 __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1);
2457 Object* obj; 2462 Object* obj;
2458 { MaybeObject* maybe_obj = GenerateMissBranch(); 2463 { MaybeObject* maybe_obj = GenerateMissBranch();
2459 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2464 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2460 } 2465 }
2461 2466
2462 // Return the generated code. 2467 // Return the generated code.
2463 return GetCode(NORMAL, name); 2468 return GetCode(NORMAL, name);
2464 } 2469 }
2465 2470
2466 2471
(...skipping 13 matching lines...) Expand all
2480 GenerateStoreField(masm(), 2485 GenerateStoreField(masm(),
2481 object, 2486 object,
2482 index, 2487 index,
2483 transition, 2488 transition,
2484 edx, ecx, ebx, 2489 edx, ecx, ebx,
2485 &miss); 2490 &miss);
2486 2491
2487 // Handle store cache miss. 2492 // Handle store cache miss.
2488 __ bind(&miss); 2493 __ bind(&miss);
2489 __ mov(ecx, Immediate(Handle<String>(name))); // restore name 2494 __ mov(ecx, Immediate(Handle<String>(name))); // restore name
2490 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2495 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2496 Builtins::StoreIC_Miss));
2491 __ jmp(ic, RelocInfo::CODE_TARGET); 2497 __ jmp(ic, RelocInfo::CODE_TARGET);
2492 2498
2493 // Return the generated code. 2499 // Return the generated code.
2494 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2500 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2495 } 2501 }
2496 2502
2497 2503
2498 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2504 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object,
2499 AccessorInfo* callback, 2505 AccessorInfo* callback,
2500 String* name) { 2506 String* name) {
(...skipping 30 matching lines...) Expand all
2531 __ push(eax); // value 2537 __ push(eax); // value
2532 __ push(ebx); // restore return address 2538 __ push(ebx); // restore return address
2533 2539
2534 // Do tail-call to the runtime system. 2540 // Do tail-call to the runtime system.
2535 ExternalReference store_callback_property = 2541 ExternalReference store_callback_property =
2536 ExternalReference(IC_Utility(IC::kStoreCallbackProperty)); 2542 ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
2537 __ TailCallExternalReference(store_callback_property, 4, 1); 2543 __ TailCallExternalReference(store_callback_property, 4, 1);
2538 2544
2539 // Handle store cache miss. 2545 // Handle store cache miss.
2540 __ bind(&miss); 2546 __ bind(&miss);
2541 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2547 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2548 Builtins::StoreIC_Miss));
2542 __ jmp(ic, RelocInfo::CODE_TARGET); 2549 __ jmp(ic, RelocInfo::CODE_TARGET);
2543 2550
2544 // Return the generated code. 2551 // Return the generated code.
2545 return GetCode(CALLBACKS, name); 2552 return GetCode(CALLBACKS, name);
2546 } 2553 }
2547 2554
2548 2555
2549 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2556 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
2550 String* name) { 2557 String* name) {
2551 // ----------- S t a t e ------------- 2558 // ----------- S t a t e -------------
(...skipping 29 matching lines...) Expand all
2581 __ push(Immediate(Smi::FromInt(strict_mode_))); 2588 __ push(Immediate(Smi::FromInt(strict_mode_)));
2582 __ push(ebx); // restore return address 2589 __ push(ebx); // restore return address
2583 2590
2584 // Do tail-call to the runtime system. 2591 // Do tail-call to the runtime system.
2585 ExternalReference store_ic_property = 2592 ExternalReference store_ic_property =
2586 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); 2593 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
2587 __ TailCallExternalReference(store_ic_property, 4, 1); 2594 __ TailCallExternalReference(store_ic_property, 4, 1);
2588 2595
2589 // Handle store cache miss. 2596 // Handle store cache miss.
2590 __ bind(&miss); 2597 __ bind(&miss);
2591 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2598 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2599 Builtins::StoreIC_Miss));
2592 __ jmp(ic, RelocInfo::CODE_TARGET); 2600 __ jmp(ic, RelocInfo::CODE_TARGET);
2593 2601
2594 // Return the generated code. 2602 // Return the generated code.
2595 return GetCode(INTERCEPTOR, name); 2603 return GetCode(INTERCEPTOR, name);
2596 } 2604 }
2597 2605
2598 2606
2599 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2607 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
2600 JSGlobalPropertyCell* cell, 2608 JSGlobalPropertyCell* cell,
2601 String* name) { 2609 String* name) {
(...skipping 15 matching lines...) Expand all
2617 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell)); 2625 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell));
2618 if (Serializer::enabled()) { 2626 if (Serializer::enabled()) {
2619 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2627 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2620 cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); 2628 cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
2621 } 2629 }
2622 2630
2623 // Check that the value in the cell is not the hole. If it is, this 2631 // Check that the value in the cell is not the hole. If it is, this
2624 // cell could have been deleted and reintroducing the global needs 2632 // cell could have been deleted and reintroducing the global needs
2625 // to update the property details in the property dictionary of the 2633 // to update the property details in the property dictionary of the
2626 // global object. We bail out to the runtime system to do that. 2634 // global object. We bail out to the runtime system to do that.
2627 __ cmp(cell_operand, Factory::the_hole_value()); 2635 __ cmp(cell_operand, FACTORY->the_hole_value());
2628 __ j(equal, &miss); 2636 __ j(equal, &miss);
2629 2637
2630 // Store the value in the cell. 2638 // Store the value in the cell.
2631 __ mov(cell_operand, eax); 2639 __ mov(cell_operand, eax);
2632 2640
2633 // Return the value (register eax). 2641 // Return the value (register eax).
2634 __ IncrementCounter(&Counters::named_store_global_inline, 1); 2642 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
2635 __ ret(0); 2643 __ ret(0);
2636 2644
2637 // Handle store cache miss. 2645 // Handle store cache miss.
2638 __ bind(&miss); 2646 __ bind(&miss);
2639 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); 2647 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
2640 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2648 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2649 Builtins::StoreIC_Miss));
2641 __ jmp(ic, RelocInfo::CODE_TARGET); 2650 __ jmp(ic, RelocInfo::CODE_TARGET);
2642 2651
2643 // Return the generated code. 2652 // Return the generated code.
2644 return GetCode(NORMAL, name); 2653 return GetCode(NORMAL, name);
2645 } 2654 }
2646 2655
2647 2656
2648 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2657 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
2649 int index, 2658 int index,
2650 Map* transition, 2659 Map* transition,
2651 String* name) { 2660 String* name) {
2652 // ----------- S t a t e ------------- 2661 // ----------- S t a t e -------------
2653 // -- eax : value 2662 // -- eax : value
2654 // -- ecx : key 2663 // -- ecx : key
2655 // -- edx : receiver 2664 // -- edx : receiver
2656 // -- esp[0] : return address 2665 // -- esp[0] : return address
2657 // ----------------------------------- 2666 // -----------------------------------
2658 Label miss; 2667 Label miss;
2659 2668
2660 __ IncrementCounter(&Counters::keyed_store_field, 1); 2669 __ IncrementCounter(COUNTERS->keyed_store_field(), 1);
2661 2670
2662 // Check that the name has not changed. 2671 // Check that the name has not changed.
2663 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 2672 __ cmp(Operand(ecx), Immediate(Handle<String>(name)));
2664 __ j(not_equal, &miss, not_taken); 2673 __ j(not_equal, &miss, not_taken);
2665 2674
2666 // Generate store field code. Trashes the name register. 2675 // Generate store field code. Trashes the name register.
2667 GenerateStoreField(masm(), 2676 GenerateStoreField(masm(),
2668 object, 2677 object,
2669 index, 2678 index,
2670 transition, 2679 transition,
2671 edx, ecx, ebx, 2680 edx, ecx, ebx,
2672 &miss); 2681 &miss);
2673 2682
2674 // Handle store cache miss. 2683 // Handle store cache miss.
2675 __ bind(&miss); 2684 __ bind(&miss);
2676 __ DecrementCounter(&Counters::keyed_store_field, 1); 2685 __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
2677 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 2686 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
2687 Builtins::KeyedStoreIC_Miss));
2678 __ jmp(ic, RelocInfo::CODE_TARGET); 2688 __ jmp(ic, RelocInfo::CODE_TARGET);
2679 2689
2680 // Return the generated code. 2690 // Return the generated code.
2681 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2691 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2682 } 2692 }
2683 2693
2684 2694
2685 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2695 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
2686 JSObject* receiver) { 2696 JSObject* receiver) {
2687 // ----------- S t a t e ------------- 2697 // ----------- S t a t e -------------
(...skipping 13 matching lines...) Expand all
2701 Immediate(Handle<Map>(receiver->map()))); 2711 Immediate(Handle<Map>(receiver->map())));
2702 __ j(not_equal, &miss, not_taken); 2712 __ j(not_equal, &miss, not_taken);
2703 2713
2704 // Check that the key is a smi. 2714 // Check that the key is a smi.
2705 __ test(ecx, Immediate(kSmiTagMask)); 2715 __ test(ecx, Immediate(kSmiTagMask));
2706 __ j(not_zero, &miss, not_taken); 2716 __ j(not_zero, &miss, not_taken);
2707 2717
2708 // Get the elements array and make sure it is a fast element array, not 'cow'. 2718 // Get the elements array and make sure it is a fast element array, not 'cow'.
2709 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 2719 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
2710 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), 2720 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
2711 Immediate(Factory::fixed_array_map())); 2721 Immediate(FACTORY->fixed_array_map()));
2712 __ j(not_equal, &miss, not_taken); 2722 __ j(not_equal, &miss, not_taken);
2713 2723
2714 // Check that the key is within bounds. 2724 // Check that the key is within bounds.
2715 if (receiver->IsJSArray()) { 2725 if (receiver->IsJSArray()) {
2716 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 2726 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
2717 __ j(above_equal, &miss, not_taken); 2727 __ j(above_equal, &miss, not_taken);
2718 } else { 2728 } else {
2719 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis. 2729 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis.
2720 __ j(above_equal, &miss, not_taken); 2730 __ j(above_equal, &miss, not_taken);
2721 } 2731 }
2722 2732
2723 // Do the store and update the write barrier. Make sure to preserve 2733 // Do the store and update the write barrier. Make sure to preserve
2724 // the value in register eax. 2734 // the value in register eax.
2725 __ mov(edx, Operand(eax)); 2735 __ mov(edx, Operand(eax));
2726 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 2736 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2727 __ RecordWrite(edi, 0, edx, ecx); 2737 __ RecordWrite(edi, 0, edx, ecx);
2728 2738
2729 // Done. 2739 // Done.
2730 __ ret(0); 2740 __ ret(0);
2731 2741
2732 // Handle store cache miss. 2742 // Handle store cache miss.
2733 __ bind(&miss); 2743 __ bind(&miss);
2734 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 2744 Handle<Code> ic(
2745 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
2735 __ jmp(ic, RelocInfo::CODE_TARGET); 2746 __ jmp(ic, RelocInfo::CODE_TARGET);
2736 2747
2737 // Return the generated code. 2748 // Return the generated code.
2738 return GetCode(NORMAL, NULL); 2749 return GetCode(NORMAL, NULL);
2739 } 2750 }
2740 2751
2741 2752
2742 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2753 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2743 JSObject* object, 2754 JSObject* object,
2744 JSObject* last) { 2755 JSObject* last) {
(...skipping 24 matching lines...) Expand all
2769 edx, 2780 edx,
2770 &miss); 2781 &miss);
2771 if (cell->IsFailure()) { 2782 if (cell->IsFailure()) {
2772 miss.Unuse(); 2783 miss.Unuse();
2773 return cell; 2784 return cell;
2774 } 2785 }
2775 } 2786 }
2776 2787
2777 // Return undefined if maps of the full prototype chain are still the 2788 // Return undefined if maps of the full prototype chain are still the
2778 // same and no global property with this name contains a value. 2789 // same and no global property with this name contains a value.
2779 __ mov(eax, Factory::undefined_value()); 2790 __ mov(eax, FACTORY->undefined_value());
2780 __ ret(0); 2791 __ ret(0);
2781 2792
2782 __ bind(&miss); 2793 __ bind(&miss);
2783 GenerateLoadMiss(masm(), Code::LOAD_IC); 2794 GenerateLoadMiss(masm(), Code::LOAD_IC);
2784 2795
2785 // Return the generated code. 2796 // Return the generated code.
2786 return GetCode(NONEXISTENT, Heap::empty_string()); 2797 return GetCode(NONEXISTENT, HEAP->empty_string());
2787 } 2798 }
2788 2799
2789 2800
2790 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 2801 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object,
2791 JSObject* holder, 2802 JSObject* holder,
2792 int index, 2803 int index,
2793 String* name) { 2804 String* name) {
2794 // ----------- S t a t e ------------- 2805 // ----------- S t a t e -------------
2795 // -- eax : receiver 2806 // -- eax : receiver
2796 // -- ecx : name 2807 // -- ecx : name
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2913 // Get the value from the cell. 2924 // Get the value from the cell.
2914 if (Serializer::enabled()) { 2925 if (Serializer::enabled()) {
2915 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2926 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2916 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 2927 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
2917 } else { 2928 } else {
2918 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 2929 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
2919 } 2930 }
2920 2931
2921 // Check for deleted property if property can actually be deleted. 2932 // Check for deleted property if property can actually be deleted.
2922 if (!is_dont_delete) { 2933 if (!is_dont_delete) {
2923 __ cmp(ebx, Factory::the_hole_value()); 2934 __ cmp(ebx, FACTORY->the_hole_value());
2924 __ j(equal, &miss, not_taken); 2935 __ j(equal, &miss, not_taken);
2925 } else if (FLAG_debug_code) { 2936 } else if (FLAG_debug_code) {
2926 __ cmp(ebx, Factory::the_hole_value()); 2937 __ cmp(ebx, FACTORY->the_hole_value());
2927 __ Check(not_equal, "DontDelete cells can't contain the hole"); 2938 __ Check(not_equal, "DontDelete cells can't contain the hole");
2928 } 2939 }
2929 2940
2930 __ IncrementCounter(&Counters::named_load_global_stub, 1); 2941 __ IncrementCounter(COUNTERS->named_load_global_stub(), 1);
2931 __ mov(eax, ebx); 2942 __ mov(eax, ebx);
2932 __ ret(0); 2943 __ ret(0);
2933 2944
2934 __ bind(&miss); 2945 __ bind(&miss);
2935 __ IncrementCounter(&Counters::named_load_global_stub_miss, 1); 2946 __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1);
2936 GenerateLoadMiss(masm(), Code::LOAD_IC); 2947 GenerateLoadMiss(masm(), Code::LOAD_IC);
2937 2948
2938 // Return the generated code. 2949 // Return the generated code.
2939 return GetCode(NORMAL, name); 2950 return GetCode(NORMAL, name);
2940 } 2951 }
2941 2952
2942 2953
2943 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 2954 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
2944 JSObject* receiver, 2955 JSObject* receiver,
2945 JSObject* holder, 2956 JSObject* holder,
2946 int index) { 2957 int index) {
2947 // ----------- S t a t e ------------- 2958 // ----------- S t a t e -------------
2948 // -- eax : key 2959 // -- eax : key
2949 // -- edx : receiver 2960 // -- edx : receiver
2950 // -- esp[0] : return address 2961 // -- esp[0] : return address
2951 // ----------------------------------- 2962 // -----------------------------------
2952 Label miss; 2963 Label miss;
2953 2964
2954 __ IncrementCounter(&Counters::keyed_load_field, 1); 2965 __ IncrementCounter(COUNTERS->keyed_load_field(), 1);
2955 2966
2956 // Check that the name has not changed. 2967 // Check that the name has not changed.
2957 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 2968 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
2958 __ j(not_equal, &miss, not_taken); 2969 __ j(not_equal, &miss, not_taken);
2959 2970
2960 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); 2971 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
2961 2972
2962 __ bind(&miss); 2973 __ bind(&miss);
2963 __ DecrementCounter(&Counters::keyed_load_field, 1); 2974 __ DecrementCounter(COUNTERS->keyed_load_field(), 1);
2964 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2975 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2965 2976
2966 // Return the generated code. 2977 // Return the generated code.
2967 return GetCode(FIELD, name); 2978 return GetCode(FIELD, name);
2968 } 2979 }
2969 2980
2970 2981
2971 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( 2982 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
2972 String* name, 2983 String* name,
2973 JSObject* receiver, 2984 JSObject* receiver,
2974 JSObject* holder, 2985 JSObject* holder,
2975 AccessorInfo* callback) { 2986 AccessorInfo* callback) {
2976 // ----------- S t a t e ------------- 2987 // ----------- S t a t e -------------
2977 // -- eax : key 2988 // -- eax : key
2978 // -- edx : receiver 2989 // -- edx : receiver
2979 // -- esp[0] : return address 2990 // -- esp[0] : return address
2980 // ----------------------------------- 2991 // -----------------------------------
2981 Label miss; 2992 Label miss;
2982 2993
2983 __ IncrementCounter(&Counters::keyed_load_callback, 1); 2994 __ IncrementCounter(COUNTERS->keyed_load_callback(), 1);
2984 2995
2985 // Check that the name has not changed. 2996 // Check that the name has not changed.
2986 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 2997 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
2987 __ j(not_equal, &miss, not_taken); 2998 __ j(not_equal, &miss, not_taken);
2988 2999
2989 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, 3000 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx,
2990 ecx, edi, callback, name, &miss); 3001 ecx, edi, callback, name, &miss);
2991 if (result->IsFailure()) { 3002 if (result->IsFailure()) {
2992 miss.Unuse(); 3003 miss.Unuse();
2993 return result; 3004 return result;
2994 } 3005 }
2995 3006
2996 __ bind(&miss); 3007 __ bind(&miss);
2997 3008
2998 __ DecrementCounter(&Counters::keyed_load_callback, 1); 3009 __ DecrementCounter(COUNTERS->keyed_load_callback(), 1);
2999 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3010 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3000 3011
3001 // Return the generated code. 3012 // Return the generated code.
3002 return GetCode(CALLBACKS, name); 3013 return GetCode(CALLBACKS, name);
3003 } 3014 }
3004 3015
3005 3016
3006 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, 3017 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
3007 JSObject* receiver, 3018 JSObject* receiver,
3008 JSObject* holder, 3019 JSObject* holder,
3009 Object* value) { 3020 Object* value) {
3010 // ----------- S t a t e ------------- 3021 // ----------- S t a t e -------------
3011 // -- eax : key 3022 // -- eax : key
3012 // -- edx : receiver 3023 // -- edx : receiver
3013 // -- esp[0] : return address 3024 // -- esp[0] : return address
3014 // ----------------------------------- 3025 // -----------------------------------
3015 Label miss; 3026 Label miss;
3016 3027
3017 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); 3028 __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1);
3018 3029
3019 // Check that the name has not changed. 3030 // Check that the name has not changed.
3020 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3031 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3021 __ j(not_equal, &miss, not_taken); 3032 __ j(not_equal, &miss, not_taken);
3022 3033
3023 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, 3034 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
3024 value, name, &miss); 3035 value, name, &miss);
3025 __ bind(&miss); 3036 __ bind(&miss);
3026 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); 3037 __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1);
3027 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3038 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3028 3039
3029 // Return the generated code. 3040 // Return the generated code.
3030 return GetCode(CONSTANT_FUNCTION, name); 3041 return GetCode(CONSTANT_FUNCTION, name);
3031 } 3042 }
3032 3043
3033 3044
3034 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3045 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3035 JSObject* holder, 3046 JSObject* holder,
3036 String* name) { 3047 String* name) {
3037 // ----------- S t a t e ------------- 3048 // ----------- S t a t e -------------
3038 // -- eax : key 3049 // -- eax : key
3039 // -- edx : receiver 3050 // -- edx : receiver
3040 // -- esp[0] : return address 3051 // -- esp[0] : return address
3041 // ----------------------------------- 3052 // -----------------------------------
3042 Label miss; 3053 Label miss;
3043 3054
3044 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); 3055 __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1);
3045 3056
3046 // Check that the name has not changed. 3057 // Check that the name has not changed.
3047 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3058 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3048 __ j(not_equal, &miss, not_taken); 3059 __ j(not_equal, &miss, not_taken);
3049 3060
3050 LookupResult lookup; 3061 LookupResult lookup;
3051 LookupPostInterceptor(holder, name, &lookup); 3062 LookupPostInterceptor(holder, name, &lookup);
3052 GenerateLoadInterceptor(receiver, 3063 GenerateLoadInterceptor(receiver,
3053 holder, 3064 holder,
3054 &lookup, 3065 &lookup,
3055 edx, 3066 edx,
3056 eax, 3067 eax,
3057 ecx, 3068 ecx,
3058 ebx, 3069 ebx,
3059 edi, 3070 edi,
3060 name, 3071 name,
3061 &miss); 3072 &miss);
3062 __ bind(&miss); 3073 __ bind(&miss);
3063 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); 3074 __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1);
3064 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3075 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3065 3076
3066 // Return the generated code. 3077 // Return the generated code.
3067 return GetCode(INTERCEPTOR, name); 3078 return GetCode(INTERCEPTOR, name);
3068 } 3079 }
3069 3080
3070 3081
3071 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3082 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
3072 // ----------- S t a t e ------------- 3083 // ----------- S t a t e -------------
3073 // -- eax : key 3084 // -- eax : key
3074 // -- edx : receiver 3085 // -- edx : receiver
3075 // -- esp[0] : return address 3086 // -- esp[0] : return address
3076 // ----------------------------------- 3087 // -----------------------------------
3077 Label miss; 3088 Label miss;
3078 3089
3079 __ IncrementCounter(&Counters::keyed_load_array_length, 1); 3090 __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1);
3080 3091
3081 // Check that the name has not changed. 3092 // Check that the name has not changed.
3082 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3093 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3083 __ j(not_equal, &miss, not_taken); 3094 __ j(not_equal, &miss, not_taken);
3084 3095
3085 GenerateLoadArrayLength(masm(), edx, ecx, &miss); 3096 GenerateLoadArrayLength(masm(), edx, ecx, &miss);
3086 __ bind(&miss); 3097 __ bind(&miss);
3087 __ DecrementCounter(&Counters::keyed_load_array_length, 1); 3098 __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1);
3088 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3099 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3089 3100
3090 // Return the generated code. 3101 // Return the generated code.
3091 return GetCode(CALLBACKS, name); 3102 return GetCode(CALLBACKS, name);
3092 } 3103 }
3093 3104
3094 3105
3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3106 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
3096 // ----------- S t a t e ------------- 3107 // ----------- S t a t e -------------
3097 // -- eax : key 3108 // -- eax : key
3098 // -- edx : receiver 3109 // -- edx : receiver
3099 // -- esp[0] : return address 3110 // -- esp[0] : return address
3100 // ----------------------------------- 3111 // -----------------------------------
3101 Label miss; 3112 Label miss;
3102 3113
3103 __ IncrementCounter(&Counters::keyed_load_string_length, 1); 3114 __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1);
3104 3115
3105 // Check that the name has not changed. 3116 // Check that the name has not changed.
3106 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3117 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3107 __ j(not_equal, &miss, not_taken); 3118 __ j(not_equal, &miss, not_taken);
3108 3119
3109 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); 3120 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
3110 __ bind(&miss); 3121 __ bind(&miss);
3111 __ DecrementCounter(&Counters::keyed_load_string_length, 1); 3122 __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1);
3112 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3123 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3113 3124
3114 // Return the generated code. 3125 // Return the generated code.
3115 return GetCode(CALLBACKS, name); 3126 return GetCode(CALLBACKS, name);
3116 } 3127 }
3117 3128
3118 3129
3119 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3130 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
3120 // ----------- S t a t e ------------- 3131 // ----------- S t a t e -------------
3121 // -- eax : key 3132 // -- eax : key
3122 // -- edx : receiver 3133 // -- edx : receiver
3123 // -- esp[0] : return address 3134 // -- esp[0] : return address
3124 // ----------------------------------- 3135 // -----------------------------------
3125 Label miss; 3136 Label miss;
3126 3137
3127 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); 3138 __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
3128 3139
3129 // Check that the name has not changed. 3140 // Check that the name has not changed.
3130 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3141 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3131 __ j(not_equal, &miss, not_taken); 3142 __ j(not_equal, &miss, not_taken);
3132 3143
3133 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3144 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3134 __ bind(&miss); 3145 __ bind(&miss);
3135 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); 3146 __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
3136 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3147 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3137 3148
3138 // Return the generated code. 3149 // Return the generated code.
3139 return GetCode(CALLBACKS, name); 3150 return GetCode(CALLBACKS, name);
3140 } 3151 }
3141 3152
3142 3153
3143 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { 3154 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
3144 // ----------- S t a t e ------------- 3155 // ----------- S t a t e -------------
3145 // -- eax : key 3156 // -- eax : key
(...skipping 19 matching lines...) Expand all
3165 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3176 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3166 __ AssertFastElements(ecx); 3177 __ AssertFastElements(ecx);
3167 3178
3168 // Check that the key is within bounds. 3179 // Check that the key is within bounds.
3169 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 3180 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3170 __ j(above_equal, &miss, not_taken); 3181 __ j(above_equal, &miss, not_taken);
3171 3182
3172 // Load the result and make sure it's not the hole. 3183 // Load the result and make sure it's not the hole.
3173 __ mov(ebx, Operand(ecx, eax, times_2, 3184 __ mov(ebx, Operand(ecx, eax, times_2,
3174 FixedArray::kHeaderSize - kHeapObjectTag)); 3185 FixedArray::kHeaderSize - kHeapObjectTag));
3175 __ cmp(ebx, Factory::the_hole_value()); 3186 __ cmp(ebx, FACTORY->the_hole_value());
3176 __ j(equal, &miss, not_taken); 3187 __ j(equal, &miss, not_taken);
3177 __ mov(eax, ebx); 3188 __ mov(eax, ebx);
3178 __ ret(0); 3189 __ ret(0);
3179 3190
3180 __ bind(&miss); 3191 __ bind(&miss);
3181 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3192 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3182 3193
3183 // Return the generated code. 3194 // Return the generated code.
3184 return GetCode(NORMAL, NULL); 3195 return GetCode(NORMAL, NULL);
3185 } 3196 }
3186 3197
3187 3198
3188 // Specialized stub for constructing objects from functions which only have only 3199 // Specialized stub for constructing objects from functions which only have only
3189 // simple assignments of the form this.x = ...; in their body. 3200 // simple assignments of the form this.x = ...; in their body.
3190 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3201 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3191 // ----------- S t a t e ------------- 3202 // ----------- S t a t e -------------
3192 // -- eax : argc 3203 // -- eax : argc
3193 // -- edi : constructor 3204 // -- edi : constructor
3194 // -- esp[0] : return address 3205 // -- esp[0] : return address
3195 // -- esp[4] : last argument 3206 // -- esp[4] : last argument
3196 // ----------------------------------- 3207 // -----------------------------------
3197 Label generic_stub_call; 3208 Label generic_stub_call;
3198 #ifdef ENABLE_DEBUGGER_SUPPORT 3209 #ifdef ENABLE_DEBUGGER_SUPPORT
3199 // Check to see whether there are any break points in the function code. If 3210 // Check to see whether there are any break points in the function code. If
3200 // there are jump to the generic constructor stub which calls the actual 3211 // there are jump to the generic constructor stub which calls the actual
3201 // code for the function thereby hitting the break points. 3212 // code for the function thereby hitting the break points.
3202 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 3213 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
3203 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset)); 3214 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset));
3204 __ cmp(ebx, Factory::undefined_value()); 3215 __ cmp(ebx, FACTORY->undefined_value());
3205 __ j(not_equal, &generic_stub_call, not_taken); 3216 __ j(not_equal, &generic_stub_call, not_taken);
3206 #endif 3217 #endif
3207 3218
3208 // Load the initial map and verify that it is in fact a map. 3219 // Load the initial map and verify that it is in fact a map.
3209 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 3220 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
3210 // Will both indicate a NULL and a Smi. 3221 // Will both indicate a NULL and a Smi.
3211 __ test(ebx, Immediate(kSmiTagMask)); 3222 __ test(ebx, Immediate(kSmiTagMask));
3212 __ j(zero, &generic_stub_call); 3223 __ j(zero, &generic_stub_call);
3213 __ CmpObjectType(ebx, MAP_TYPE, ecx); 3224 __ CmpObjectType(ebx, MAP_TYPE, ecx);
3214 __ j(not_equal, &generic_stub_call); 3225 __ j(not_equal, &generic_stub_call);
(...skipping 16 matching lines...) Expand all
3231 edx, 3242 edx,
3232 ecx, 3243 ecx,
3233 no_reg, 3244 no_reg,
3234 &generic_stub_call, 3245 &generic_stub_call,
3235 NO_ALLOCATION_FLAGS); 3246 NO_ALLOCATION_FLAGS);
3236 3247
3237 // Allocated the JSObject, now initialize the fields and add the heap tag. 3248 // Allocated the JSObject, now initialize the fields and add the heap tag.
3238 // ebx: initial map 3249 // ebx: initial map
3239 // edx: JSObject (untagged) 3250 // edx: JSObject (untagged)
3240 __ mov(Operand(edx, JSObject::kMapOffset), ebx); 3251 __ mov(Operand(edx, JSObject::kMapOffset), ebx);
3241 __ mov(ebx, Factory::empty_fixed_array()); 3252 __ mov(ebx, FACTORY->empty_fixed_array());
3242 __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx); 3253 __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx);
3243 __ mov(Operand(edx, JSObject::kElementsOffset), ebx); 3254 __ mov(Operand(edx, JSObject::kElementsOffset), ebx);
3244 3255
3245 // Push the allocated object to the stack. This is the object that will be 3256 // Push the allocated object to the stack. This is the object that will be
3246 // returned (after it is tagged). 3257 // returned (after it is tagged).
3247 __ push(edx); 3258 __ push(edx);
3248 3259
3249 // eax: argc 3260 // eax: argc
3250 // edx: JSObject (untagged) 3261 // edx: JSObject (untagged)
3251 // Load the address of the first in-object property into edx. 3262 // Load the address of the first in-object property into edx.
3252 __ lea(edx, Operand(edx, JSObject::kHeaderSize)); 3263 __ lea(edx, Operand(edx, JSObject::kHeaderSize));
3253 // Calculate the location of the first argument. The stack contains the 3264 // Calculate the location of the first argument. The stack contains the
3254 // allocated object and the return address on top of the argc arguments. 3265 // allocated object and the return address on top of the argc arguments.
3255 __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize)); 3266 __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize));
3256 3267
3257 // Use edi for holding undefined which is used in several places below. 3268 // Use edi for holding undefined which is used in several places below.
3258 __ mov(edi, Factory::undefined_value()); 3269 __ mov(edi, FACTORY->undefined_value());
3259 3270
3260 // eax: argc 3271 // eax: argc
3261 // ecx: first argument 3272 // ecx: first argument
3262 // edx: first in-object property of the JSObject 3273 // edx: first in-object property of the JSObject
3263 // edi: undefined 3274 // edi: undefined
3264 // Fill the initialized properties with a constant value or a passed argument 3275 // Fill the initialized properties with a constant value or a passed argument
3265 // depending on the this.x = ...; assignment in the function. 3276 // depending on the this.x = ...; assignment in the function.
3266 SharedFunctionInfo* shared = function->shared(); 3277 SharedFunctionInfo* shared = function->shared();
3267 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3278 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3268 if (shared->IsThisPropertyAssignmentArgument(i)) { 3279 if (shared->IsThisPropertyAssignmentArgument(i)) {
3269 // Check if the argument assigned to the property is actually passed. 3280 // Check if the argument assigned to the property is actually passed.
3270 // If argument is not passed the property is set to undefined, 3281 // If argument is not passed the property is set to undefined,
3271 // otherwise find it on the stack. 3282 // otherwise find it on the stack.
3272 int arg_number = shared->GetThisPropertyAssignmentArgument(i); 3283 int arg_number = shared->GetThisPropertyAssignmentArgument(i);
3273 __ mov(ebx, edi); 3284 __ mov(ebx, edi);
3274 __ cmp(eax, arg_number); 3285 __ cmp(eax, arg_number);
3275 if (CpuFeatures::IsSupported(CMOV)) { 3286 if (Isolate::Current()->cpu_features()->IsSupported(CMOV)) {
3276 CpuFeatures::Scope use_cmov(CMOV); 3287 CpuFeatures::Scope use_cmov(CMOV);
3277 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); 3288 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
3278 } else { 3289 } else {
3279 Label not_passed; 3290 Label not_passed;
3280 __ j(below_equal, &not_passed); 3291 __ j(below_equal, &not_passed);
3281 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); 3292 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
3282 __ bind(&not_passed); 3293 __ bind(&not_passed);
3283 } 3294 }
3284 // Store value in the property. 3295 // Store value in the property.
3285 __ mov(Operand(edx, i * kPointerSize), ebx); 3296 __ mov(Operand(edx, i * kPointerSize), ebx);
(...skipping 14 matching lines...) Expand all
3300 3311
3301 // Move argc to ebx and retrieve and tag the JSObject to return. 3312 // Move argc to ebx and retrieve and tag the JSObject to return.
3302 __ mov(ebx, eax); 3313 __ mov(ebx, eax);
3303 __ pop(eax); 3314 __ pop(eax);
3304 __ or_(Operand(eax), Immediate(kHeapObjectTag)); 3315 __ or_(Operand(eax), Immediate(kHeapObjectTag));
3305 3316
3306 // Remove caller arguments and receiver from the stack and return. 3317 // Remove caller arguments and receiver from the stack and return.
3307 __ pop(ecx); 3318 __ pop(ecx);
3308 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); 3319 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
3309 __ push(ecx); 3320 __ push(ecx);
3310 __ IncrementCounter(&Counters::constructed_objects, 1); 3321 __ IncrementCounter(COUNTERS->constructed_objects(), 1);
3311 __ IncrementCounter(&Counters::constructed_objects_stub, 1); 3322 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
3312 __ ret(0); 3323 __ ret(0);
3313 3324
3314 // Jump to the generic stub in case the specialized code cannot handle the 3325 // Jump to the generic stub in case the specialized code cannot handle the
3315 // construction. 3326 // construction.
3316 __ bind(&generic_stub_call); 3327 __ bind(&generic_stub_call);
3317 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); 3328 Code* code = Isolate::Current()->builtins()->builtin(
3329 Builtins::JSConstructStubGeneric);
3318 Handle<Code> generic_construct_stub(code); 3330 Handle<Code> generic_construct_stub(code);
3319 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3331 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3320 3332
3321 // Return the generated code. 3333 // Return the generated code.
3322 return GetCode(); 3334 return GetCode();
3323 } 3335 }
3324 3336
3325 3337
3326 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3338 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3327 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3339 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3448 3460
3449 // If we fail allocation of the HeapNumber, we still have a value on 3461 // If we fail allocation of the HeapNumber, we still have a value on
3450 // top of the FPU stack. Remove it. 3462 // top of the FPU stack. Remove it.
3451 __ bind(&failed_allocation); 3463 __ bind(&failed_allocation);
3452 __ ffree(); 3464 __ ffree();
3453 __ fincstp(); 3465 __ fincstp();
3454 // Fall through to slow case. 3466 // Fall through to slow case.
3455 3467
3456 // Slow case: Jump to runtime. 3468 // Slow case: Jump to runtime.
3457 __ bind(&slow); 3469 __ bind(&slow);
3458 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); 3470 __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1);
3459 // ----------- S t a t e ------------- 3471 // ----------- S t a t e -------------
3460 // -- eax : key 3472 // -- eax : key
3461 // -- edx : receiver 3473 // -- edx : receiver
3462 // -- esp[0] : return address 3474 // -- esp[0] : return address
3463 // ----------------------------------- 3475 // -----------------------------------
3464 3476
3465 __ pop(ebx); 3477 __ pop(ebx);
3466 __ push(edx); // receiver 3478 __ push(edx); // receiver
3467 __ push(eax); // name 3479 __ push(eax); // name
3468 __ push(ebx); // return address 3480 __ push(ebx); // return address
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 3573
3562 // TODO(danno): handle heap number -> pixel array conversion 3574 // TODO(danno): handle heap number -> pixel array conversion
3563 if (array_type != kExternalPixelArray) { 3575 if (array_type != kExternalPixelArray) {
3564 __ bind(&check_heap_number); 3576 __ bind(&check_heap_number);
3565 // eax: value 3577 // eax: value
3566 // edx: receiver 3578 // edx: receiver
3567 // ecx: key 3579 // ecx: key
3568 // edi: elements array 3580 // edi: elements array
3569 // ebx: untagged index 3581 // ebx: untagged index
3570 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3582 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3571 Immediate(Factory::heap_number_map())); 3583 Immediate(FACTORY->heap_number_map()));
3572 __ j(not_equal, &slow); 3584 __ j(not_equal, &slow);
3573 3585
3574 // The WebGL specification leaves the behavior of storing NaN and 3586 // The WebGL specification leaves the behavior of storing NaN and
3575 // +/-Infinity into integer arrays basically undefined. For more 3587 // +/-Infinity into integer arrays basically undefined. For more
3576 // reproducible behavior, convert these to zero. 3588 // reproducible behavior, convert these to zero.
3577 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3589 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3578 // ebx: untagged index 3590 // ebx: untagged index
3579 // edi: base pointer of external storage 3591 // edi: base pointer of external storage
3580 if (array_type == kExternalFloatArray) { 3592 if (array_type == kExternalFloatArray) {
3581 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3593 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3582 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3594 __ fstp_s(Operand(edi, ebx, times_4, 0));
3583 __ ret(0); 3595 __ ret(0);
3584 } else { 3596 } else {
3585 // Perform float-to-int conversion with truncation (round-to-zero) 3597 // Perform float-to-int conversion with truncation (round-to-zero)
3586 // behavior. 3598 // behavior.
3587 3599
3588 // For the moment we make the slow call to the runtime on 3600 // For the moment we make the slow call to the runtime on
3589 // processors that don't support SSE2. The code in IntegerConvert 3601 // processors that don't support SSE2. The code in IntegerConvert
3590 // (code-stubs-ia32.cc) is roughly what is needed here though the 3602 // (code-stubs-ia32.cc) is roughly what is needed here though the
3591 // conversion failure case does not need to be handled. 3603 // conversion failure case does not need to be handled.
3592 if (CpuFeatures::IsSupported(SSE2)) { 3604 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) {
3593 if (array_type != kExternalIntArray && 3605 if (array_type != kExternalIntArray &&
3594 array_type != kExternalUnsignedIntArray) { 3606 array_type != kExternalUnsignedIntArray) {
3595 ASSERT(CpuFeatures::IsSupported(SSE2)); 3607 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3596 CpuFeatures::Scope scope(SSE2); 3608 CpuFeatures::Scope scope(SSE2);
3597 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); 3609 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3598 // ecx: untagged integer value 3610 // ecx: untagged integer value
3599 switch (array_type) { 3611 switch (array_type) {
3600 case kExternalPixelArray: 3612 case kExternalPixelArray:
3601 { // Clamp the value to [0..255]. 3613 { // Clamp the value to [0..255].
3602 NearLabel done; 3614 NearLabel done;
3603 __ test(ecx, Immediate(0xFFFFFF00)); 3615 __ test(ecx, Immediate(0xFFFFFF00));
3604 __ j(zero, &done); 3616 __ j(zero, &done);
3605 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3617 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3606 __ dec_b(ecx); // 0 if negative, 255 if positive. 3618 __ dec_b(ecx); // 0 if negative, 255 if positive.
3607 __ bind(&done); 3619 __ bind(&done);
3608 } 3620 }
3609 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3621 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3610 case kExternalByteArray: 3622 case kExternalByteArray:
3611 case kExternalUnsignedByteArray: 3623 case kExternalUnsignedByteArray:
3612 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3624 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3613 break; 3625 break;
3614 case kExternalShortArray: 3626 case kExternalShortArray:
3615 case kExternalUnsignedShortArray: 3627 case kExternalUnsignedShortArray:
3616 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3628 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3617 break; 3629 break;
3618 default: 3630 default:
3619 UNREACHABLE(); 3631 UNREACHABLE();
3620 break; 3632 break;
3621 } 3633 }
3622 } else { 3634 } else {
3623 if (CpuFeatures::IsSupported(SSE3)) { 3635 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) {
3624 CpuFeatures::Scope scope(SSE3); 3636 CpuFeatures::Scope scope(SSE3);
3625 // fisttp stores values as signed integers. To represent the 3637 // fisttp stores values as signed integers. To represent the
3626 // entire range of int and unsigned int arrays, store as a 3638 // entire range of int and unsigned int arrays, store as a
3627 // 64-bit int and discard the high 32 bits. 3639 // 64-bit int and discard the high 32 bits.
3628 // If the value is NaN or +/-infinity, the result is 0x80000000, 3640 // If the value is NaN or +/-infinity, the result is 0x80000000,
3629 // which is automatically zero when taken mod 2^n, n < 32. 3641 // which is automatically zero when taken mod 2^n, n < 32.
3630 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3642 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3631 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3643 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3632 __ fisttp_d(Operand(esp, 0)); 3644 __ fisttp_d(Operand(esp, 0));
3633 __ pop(ecx); 3645 __ pop(ecx);
3634 __ add(Operand(esp), Immediate(kPointerSize)); 3646 __ add(Operand(esp), Immediate(kPointerSize));
3635 } else { 3647 } else {
3636 ASSERT(CpuFeatures::IsSupported(SSE2)); 3648 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
3637 CpuFeatures::Scope scope(SSE2); 3649 CpuFeatures::Scope scope(SSE2);
3638 // We can easily implement the correct rounding behavior for the 3650 // We can easily implement the correct rounding behavior for the
3639 // range [0, 2^31-1]. For the time being, to keep this code simple, 3651 // range [0, 2^31-1]. For the time being, to keep this code simple,
3640 // make the slow runtime call for values outside this range. 3652 // make the slow runtime call for values outside this range.
3641 // Note: we could do better for signed int arrays. 3653 // Note: we could do better for signed int arrays.
3642 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3654 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3643 // We will need the key if we have to make the slow runtime call. 3655 // We will need the key if we have to make the slow runtime call.
3644 __ push(ecx); 3656 __ push(ecx);
3645 __ LoadPowerOf2(xmm1, ecx, 31); 3657 __ LoadPowerOf2(xmm1, ecx, 31);
3646 __ pop(ecx); 3658 __ pop(ecx);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3679 3691
3680 return GetCode(flags); 3692 return GetCode(flags);
3681 } 3693 }
3682 3694
3683 3695
3684 #undef __ 3696 #undef __
3685 3697
3686 } } // namespace v8::internal 3698 } } // namespace v8::internal
3687 3699
3688 #endif // V8_TARGET_ARCH_IA32 3700 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/simulator-ia32.h ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698