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

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

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month 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/arm/simulator-arm.cc ('k') | src/array.js » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Miss: fall through. 88 // Miss: fall through.
89 __ bind(&miss); 89 __ bind(&miss);
90 } 90 }
91 91
92 92
93 // Helper function used to check that the dictionary doesn't contain 93 // Helper function used to check that the dictionary doesn't contain
94 // the property. This function may return false negatives, so miss_label 94 // the property. This function may return false negatives, so miss_label
95 // must always call a backup property check that is complete. 95 // must always call a backup property check that is complete.
96 // This function is safe to call if the receiver has fast properties. 96 // This function is safe to call if the receiver has fast properties.
97 // Name must be a symbol and receiver must be a heap object. 97 // Name must be a symbol and receiver must be a heap object.
98 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( 98 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
99 Label* miss_label,
100 Register receiver,
101 Handle<String> name,
102 Register scratch0,
103 Register scratch1) {
104 ASSERT(name->IsSymbol());
105 Counters* counters = masm->isolate()->counters();
106 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
107 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
108
109 Label done;
110
111 const int kInterceptorOrAccessCheckNeededMask =
112 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
113
114 // Bail out if the receiver has a named interceptor or requires access checks.
115 Register map = scratch1;
116 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
117 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
118 __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
119 __ b(ne, miss_label);
120
121 // Check that receiver is a JSObject.
122 __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
123 __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
124 __ b(lt, miss_label);
125
126 // Load properties array.
127 Register properties = scratch0;
128 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
129 // Check that the properties array is a dictionary.
130 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset));
131 Register tmp = properties;
132 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
133 __ cmp(map, tmp);
134 __ b(ne, miss_label);
135
136 // Restore the temporarily used register.
137 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
138
139
140 StringDictionaryLookupStub::GenerateNegativeLookup(masm,
141 miss_label,
142 &done,
143 receiver,
144 properties,
145 name,
146 scratch1);
147 __ bind(&done);
148 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
149 }
150
151
152 // TODO(kmillikin): Eliminate this function when the stub cache is fully
153 // handlified.
154 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup(
99 MacroAssembler* masm, 155 MacroAssembler* masm,
100 Label* miss_label, 156 Label* miss_label,
101 Register receiver, 157 Register receiver,
102 String* name, 158 String* name,
103 Register scratch0, 159 Register scratch0,
104 Register scratch1) { 160 Register scratch1) {
105 ASSERT(name->IsSymbol()); 161 ASSERT(name->IsSymbol());
106 Counters* counters = masm->isolate()->counters(); 162 Counters* counters = masm->isolate()->counters();
107 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 163 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
108 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 164 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
(...skipping 22 matching lines...) Expand all
131 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 187 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset));
132 Register tmp = properties; 188 Register tmp = properties;
133 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 189 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
134 __ cmp(map, tmp); 190 __ cmp(map, tmp);
135 __ b(ne, miss_label); 191 __ b(ne, miss_label);
136 192
137 // Restore the temporarily used register. 193 // Restore the temporarily used register.
138 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 194 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
139 195
140 196
141 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( 197 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup(
142 masm, 198 masm,
143 miss_label, 199 miss_label,
144 &done, 200 &done,
145 receiver, 201 receiver,
146 properties, 202 properties,
147 name, 203 name,
148 scratch1); 204 scratch1);
149 if (result->IsFailure()) return result; 205 if (result->IsFailure()) return result;
150 206
151 __ bind(&done); 207 __ bind(&done);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 __ Move(prototype, Handle<Map>(function->initial_map())); 308 __ Move(prototype, Handle<Map>(function->initial_map()));
253 // Load the prototype from the initial map. 309 // Load the prototype from the initial map.
254 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 310 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
255 } 311 }
256 312
257 313
258 // Load a fast property out of a holder object (src). In-object properties 314 // Load a fast property out of a holder object (src). In-object properties
259 // are loaded directly otherwise the property is loaded from the properties 315 // are loaded directly otherwise the property is loaded from the properties
260 // fixed array. 316 // fixed array.
261 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 317 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
262 Register dst, Register src, 318 Register dst,
263 JSObject* holder, int index) { 319 Register src,
320 Handle<JSObject> holder,
321 int index) {
264 // Adjust for the number of properties stored in the holder. 322 // Adjust for the number of properties stored in the holder.
265 index -= holder->map()->inobject_properties(); 323 index -= holder->map()->inobject_properties();
266 if (index < 0) { 324 if (index < 0) {
267 // Get the property straight out of the holder. 325 // Get the property straight out of the holder.
268 int offset = holder->map()->instance_size() + (index * kPointerSize); 326 int offset = holder->map()->instance_size() + (index * kPointerSize);
269 __ ldr(dst, FieldMemOperand(src, offset)); 327 __ ldr(dst, FieldMemOperand(src, offset));
270 } else { 328 } else {
271 // Calculate the offset into the properties array. 329 // Calculate the offset into the properties array.
272 int offset = index * kPointerSize + FixedArray::kHeaderSize; 330 int offset = index * kPointerSize + FixedArray::kHeaderSize;
273 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 331 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 __ mov(r0, scratch1); 418 __ mov(r0, scratch1);
361 __ Ret(); 419 __ Ret();
362 } 420 }
363 421
364 422
365 // Generate StoreField code, value is passed in r0 register. 423 // Generate StoreField code, value is passed in r0 register.
366 // When leaving generated code after success, the receiver_reg and name_reg 424 // When leaving generated code after success, the receiver_reg and name_reg
367 // may be clobbered. Upon branch to miss_label, the receiver and name 425 // may be clobbered. Upon branch to miss_label, the receiver and name
368 // registers have their original values. 426 // registers have their original values.
369 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 427 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
370 JSObject* object, 428 Handle<JSObject> object,
371 int index, 429 int index,
372 Map* transition, 430 Handle<Map> transition,
373 Register receiver_reg, 431 Register receiver_reg,
374 Register name_reg, 432 Register name_reg,
375 Register scratch, 433 Register scratch,
376 Label* miss_label) { 434 Label* miss_label) {
377 // r0 : value 435 // r0 : value
378 Label exit; 436 Label exit;
379 437
380 // Check that the receiver isn't a smi. 438 // Check that the receiver isn't a smi.
381 __ JumpIfSmi(receiver_reg, miss_label); 439 __ JumpIfSmi(receiver_reg, miss_label);
382 440
383 // Check that the map of the receiver hasn't changed. 441 // Check that the map of the receiver hasn't changed.
384 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 442 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
385 __ cmp(scratch, Operand(Handle<Map>(object->map()))); 443 __ cmp(scratch, Operand(Handle<Map>(object->map())));
386 __ b(ne, miss_label); 444 __ b(ne, miss_label);
387 445
388 // Perform global security token check if needed. 446 // Perform global security token check if needed.
389 if (object->IsJSGlobalProxy()) { 447 if (object->IsJSGlobalProxy()) {
390 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 448 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
391 } 449 }
392 450
393 // Stub never generated for non-global objects that require access 451 // Stub never generated for non-global objects that require access
394 // checks. 452 // checks.
395 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 453 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
396 454
397 // Perform map transition for the receiver if necessary. 455 // Perform map transition for the receiver if necessary.
398 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { 456 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
399 // The properties must be extended before we can store the value. 457 // The properties must be extended before we can store the value.
400 // We jump to a runtime call that extends the properties array. 458 // We jump to a runtime call that extends the properties array.
401 __ push(receiver_reg); 459 __ push(receiver_reg);
402 __ mov(r2, Operand(Handle<Map>(transition))); 460 __ mov(r2, Operand(transition));
403 __ Push(r2, r0); 461 __ Push(r2, r0);
404 __ TailCallExternalReference( 462 __ TailCallExternalReference(
405 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 463 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
406 masm->isolate()), 464 masm->isolate()),
407 3, 465 3,
408 1); 466 1);
409 return; 467 return;
410 } 468 }
411 469
412 if (transition != NULL) { 470 if (!transition.is_null()) {
413 // Update the map of the object; no write barrier updating is 471 // Update the map of the object; no write barrier updating is
414 // needed because the map is never in new space. 472 // needed because the map is never in new space.
415 __ mov(ip, Operand(Handle<Map>(transition))); 473 __ mov(ip, Operand(transition));
416 __ str(ip, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 474 __ str(ip, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
417 } 475 }
418 476
419 // Adjust for the number of properties stored in the object. Even in the 477 // Adjust for the number of properties stored in the object. Even in the
420 // face of a transition we can use the old map here because the size of the 478 // face of a transition we can use the old map here because the size of the
421 // object and the number of in-object properties is not going to change. 479 // object and the number of in-object properties is not going to change.
422 index -= object->map()->inobject_properties(); 480 index -= object->map()->inobject_properties();
423 481
424 if (index < 0) { 482 if (index < 0) {
425 // Set the property straight into the object. 483 // Set the property straight into the object.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 } 518 }
461 519
462 // Return the value (register r0). 520 // Return the value (register r0).
463 __ bind(&exit); 521 __ bind(&exit);
464 __ Ret(); 522 __ Ret();
465 } 523 }
466 524
467 525
468 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 526 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
469 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 527 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
470 Code* code = NULL; 528 Handle<Code> code = (kind == Code::LOAD_IC)
471 if (kind == Code::LOAD_IC) { 529 ? masm->isolate()->builtins()->LoadIC_Miss()
472 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 530 : masm->isolate()->builtins()->KeyedLoadIC_Miss();
473 } else { 531 __ Jump(code, RelocInfo::CODE_TARGET);
474 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
475 }
476
477 Handle<Code> ic(code);
478 __ Jump(ic, RelocInfo::CODE_TARGET);
479 } 532 }
480 533
481 534
482 static void GenerateCallFunction(MacroAssembler* masm, 535 static void GenerateCallFunction(MacroAssembler* masm,
483 Object* object, 536 Handle<Object> object,
484 const ParameterCount& arguments, 537 const ParameterCount& arguments,
485 Label* miss, 538 Label* miss,
486 Code::ExtraICState extra_ic_state) { 539 Code::ExtraICState extra_ic_state) {
487 // ----------- S t a t e ------------- 540 // ----------- S t a t e -------------
488 // -- r0: receiver 541 // -- r0: receiver
489 // -- r1: function to call 542 // -- r1: function to call
490 // ----------------------------------- 543 // -----------------------------------
491 544
492 // Check that the function really is a function. 545 // Check that the function really is a function.
493 __ JumpIfSmi(r1, miss); 546 __ JumpIfSmi(r1, miss);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 StubCompiler* stub_compiler_; 914 StubCompiler* stub_compiler_;
862 const ParameterCount& arguments_; 915 const ParameterCount& arguments_;
863 Register name_; 916 Register name_;
864 Code::ExtraICState extra_ic_state_; 917 Code::ExtraICState extra_ic_state_;
865 }; 918 };
866 919
867 920
868 // Generate code to check that a global property cell is empty. Create 921 // Generate code to check that a global property cell is empty. Create
869 // the property cell at compilation time if no cell exists for the 922 // the property cell at compilation time if no cell exists for the
870 // property. 923 // property.
871 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( 924 static void GenerateCheckPropertyCell(MacroAssembler* masm,
925 Handle<GlobalObject> global,
926 Handle<String> name,
927 Register scratch,
928 Label* miss) {
929 Handle<JSGlobalPropertyCell> cell =
930 GlobalObject::EnsurePropertyCell(global, name);
931 ASSERT(cell->value()->IsTheHole());
932 __ mov(scratch, Operand(cell));
933 __ ldr(scratch,
934 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
935 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
936 __ cmp(scratch, ip);
937 __ b(ne, miss);
938 }
939
940
941 // TODO(kmillikin): Eliminate this function when the stub cache is fully
942 // handlified.
943 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
872 MacroAssembler* masm, 944 MacroAssembler* masm,
873 GlobalObject* global, 945 GlobalObject* global,
874 String* name, 946 String* name,
875 Register scratch, 947 Register scratch,
876 Label* miss) { 948 Label* miss) {
877 Object* probe; 949 Object* probe;
878 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 950 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
879 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 951 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
880 } 952 }
881 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 953 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
882 ASSERT(cell->value()->IsTheHole()); 954 ASSERT(cell->value()->IsTheHole());
883 __ mov(scratch, Operand(Handle<Object>(cell))); 955 __ mov(scratch, Operand(Handle<Object>(cell)));
884 __ ldr(scratch, 956 __ ldr(scratch,
885 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); 957 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
886 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 958 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
887 __ cmp(scratch, ip); 959 __ cmp(scratch, ip);
888 __ b(ne, miss); 960 __ b(ne, miss);
889 return cell; 961 return cell;
890 } 962 }
891 963
964
892 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 965 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
893 // from object to (but not including) holder. 966 // from object to (but not including) holder.
894 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( 967 static void GenerateCheckPropertyCells(MacroAssembler* masm,
968 Handle<JSObject> object,
969 Handle<JSObject> holder,
970 Handle<String> name,
971 Register scratch,
972 Label* miss) {
973 Handle<JSObject> current = object;
974 while (!current.is_identical_to(holder)) {
975 if (current->IsGlobalObject()) {
976 GenerateCheckPropertyCell(masm,
977 Handle<GlobalObject>::cast(current),
978 name,
979 scratch,
980 miss);
981 }
982 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
983 }
984 }
985
986
987 // TODO(kmillikin): Eliminate this function when the stub cache is fully
988 // handlified.
989 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
895 MacroAssembler* masm, 990 MacroAssembler* masm,
896 JSObject* object, 991 JSObject* object,
897 JSObject* holder, 992 JSObject* holder,
898 String* name, 993 String* name,
899 Register scratch, 994 Register scratch,
900 Label* miss) { 995 Label* miss) {
901 JSObject* current = object; 996 JSObject* current = object;
902 while (current != holder) { 997 while (current != holder) {
903 if (current->IsGlobalObject()) { 998 if (current->IsGlobalObject()) {
904 // Returns a cell or a failure. 999 // Returns a cell or a failure.
905 MaybeObject* result = GenerateCheckPropertyCell( 1000 MaybeObject* result = TryGenerateCheckPropertyCell(
906 masm, 1001 masm,
907 GlobalObject::cast(current), 1002 GlobalObject::cast(current),
908 name, 1003 name,
909 scratch, 1004 scratch,
910 miss); 1005 miss);
911 if (result->IsFailure()) return result; 1006 if (result->IsFailure()) return result;
912 } 1007 }
913 ASSERT(current->IsJSObject()); 1008 ASSERT(current->IsJSObject());
914 current = JSObject::cast(current->GetPrototype()); 1009 current = JSObject::cast(current->GetPrototype());
915 } 1010 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 if (!(biased_exponent & 1)) { 1115 if (!(biased_exponent & 1)) {
1021 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); 1116 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift));
1022 } 1117 }
1023 } 1118 }
1024 1119
1025 1120
1026 #undef __ 1121 #undef __
1027 #define __ ACCESS_MASM(masm()) 1122 #define __ ACCESS_MASM(masm())
1028 1123
1029 1124
1125 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1126 Register object_reg,
1127 Handle<JSObject> holder,
1128 Register holder_reg,
1129 Register scratch1,
1130 Register scratch2,
1131 Handle<String> name,
1132 int save_at_depth,
1133 Label* miss) {
1134 // Make sure there's no overlap between holder and object registers.
1135 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1136 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1137 && !scratch2.is(scratch1));
1138
1139 // Keep track of the current object in register reg.
1140 Register reg = object_reg;
1141 int depth = 0;
1142
1143 if (save_at_depth == depth) {
1144 __ str(reg, MemOperand(sp));
1145 }
1146
1147 // Check the maps in the prototype chain.
1148 // Traverse the prototype chain from the object and do map checks.
1149 Handle<JSObject> current = object;
1150 while (!current.is_identical_to(holder)) {
1151 ++depth;
1152
1153 // Only global objects and objects that do not require access
1154 // checks are allowed in stubs.
1155 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
1156
1157 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype()));
1158 if (!current->HasFastProperties() &&
1159 !current->IsJSGlobalObject() &&
1160 !current->IsJSGlobalProxy()) {
1161 if (!name->IsSymbol()) {
1162 name = factory()->LookupSymbol(name);
1163 }
1164 ASSERT(current->property_dictionary()->FindEntry(*name) ==
1165 StringDictionary::kNotFound);
1166
1167 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1168 scratch1, scratch2);
1169
1170 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1171 reg = holder_reg; // From now on the object will be in holder_reg.
1172 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1173 } else {
1174 Handle<Map> current_map(current->map());
1175 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1176 __ cmp(scratch1, Operand(current_map));
1177 // Branch on the result of the map check.
1178 __ b(ne, miss);
1179 // Check access rights to the global object. This has to happen after
1180 // the map check so that we know that the object is actually a global
1181 // object.
1182 if (current->IsJSGlobalProxy()) {
1183 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1184 }
1185 reg = holder_reg; // From now on the object will be in holder_reg.
1186
1187 if (heap()->InNewSpace(*prototype)) {
1188 // The prototype is in new space; we cannot store a reference to it
1189 // in the code. Load it from the map.
1190 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1191 } else {
1192 // The prototype is in old space; load it directly.
1193 __ mov(reg, Operand(prototype));
1194 }
1195 }
1196
1197 if (save_at_depth == depth) {
1198 __ str(reg, MemOperand(sp));
1199 }
1200
1201 // Go to the next object in the prototype chain.
1202 current = prototype;
1203 }
1204
1205 // Log the check depth.
1206 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1207
1208 // Check the holder map.
1209 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1210 __ cmp(scratch1, Operand(Handle<Map>(current->map())));
1211 __ b(ne, miss);
1212
1213 // Perform security check for access to the global object.
1214 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1215 if (holder->IsJSGlobalProxy()) {
1216 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1217 }
1218
1219 // If we've skipped any global objects, it's not enough to verify that
1220 // their maps haven't changed. We also need to check that the property
1221 // cell for the property is still empty.
1222 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1223
1224 // Return the register containing the holder.
1225 return reg;
1226 }
1227
1228
1229 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1230 // handlified.
1030 Register StubCompiler::CheckPrototypes(JSObject* object, 1231 Register StubCompiler::CheckPrototypes(JSObject* object,
1031 Register object_reg, 1232 Register object_reg,
1032 JSObject* holder, 1233 JSObject* holder,
1033 Register holder_reg, 1234 Register holder_reg,
1034 Register scratch1, 1235 Register scratch1,
1035 Register scratch2, 1236 Register scratch2,
1036 String* name, 1237 String* name,
1037 int save_at_depth, 1238 int save_at_depth,
1038 Label* miss) { 1239 Label* miss) {
1039 // Make sure there's no overlap between holder and object registers. 1240 // Make sure there's no overlap between holder and object registers.
(...skipping 29 matching lines...) Expand all
1069 Object* lookup_result = NULL; // Initialization to please compiler. 1270 Object* lookup_result = NULL; // Initialization to please compiler.
1070 if (!maybe_lookup_result->ToObject(&lookup_result)) { 1271 if (!maybe_lookup_result->ToObject(&lookup_result)) {
1071 set_failure(Failure::cast(maybe_lookup_result)); 1272 set_failure(Failure::cast(maybe_lookup_result));
1072 return reg; 1273 return reg;
1073 } 1274 }
1074 name = String::cast(lookup_result); 1275 name = String::cast(lookup_result);
1075 } 1276 }
1076 ASSERT(current->property_dictionary()->FindEntry(name) == 1277 ASSERT(current->property_dictionary()->FindEntry(name) ==
1077 StringDictionary::kNotFound); 1278 StringDictionary::kNotFound);
1078 1279
1079 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), 1280 MaybeObject* negative_lookup =
1080 miss, 1281 TryGenerateDictionaryNegativeLookup(masm(),
1081 reg, 1282 miss,
1082 name, 1283 reg,
1083 scratch1, 1284 name,
1084 scratch2); 1285 scratch1,
1286 scratch2);
1085 if (negative_lookup->IsFailure()) { 1287 if (negative_lookup->IsFailure()) {
1086 set_failure(Failure::cast(negative_lookup)); 1288 set_failure(Failure::cast(negative_lookup));
1087 return reg; 1289 return reg;
1088 } 1290 }
1089 1291
1090 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1292 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1091 reg = holder_reg; // from now the object is in holder_reg 1293 reg = holder_reg; // from now the object is in holder_reg
1092 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1294 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1093 } else if (heap()->InNewSpace(prototype)) { 1295 } else if (heap()->InNewSpace(prototype)) {
1094 // Get the map of the current object. 1296 // Get the map of the current object.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); 1345 __ cmp(scratch1, Operand(Handle<Map>(current->map())));
1144 __ b(ne, miss); 1346 __ b(ne, miss);
1145 1347
1146 // Log the check depth. 1348 // Log the check depth.
1147 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); 1349 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1148 1350
1149 // Perform security check for access to the global object. 1351 // Perform security check for access to the global object.
1150 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1352 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1151 if (holder->IsJSGlobalProxy()) { 1353 if (holder->IsJSGlobalProxy()) {
1152 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1354 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1153 }; 1355 }
1154 1356
1155 // If we've skipped any global objects, it's not enough to verify 1357 // If we've skipped any global objects, it's not enough to verify
1156 // that their maps haven't changed. We also need to check that the 1358 // that their maps haven't changed. We also need to check that the
1157 // property cell for the property is still empty. 1359 // property cell for the property is still empty.
1158 MaybeObject* result = GenerateCheckPropertyCells(masm(), 1360 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
1159 object, 1361 object,
1160 holder, 1362 holder,
1161 name, 1363 name,
1162 scratch1, 1364 scratch1,
1163 miss); 1365 miss);
1164 if (result->IsFailure()) set_failure(Failure::cast(result)); 1366 if (result->IsFailure()) set_failure(Failure::cast(result));
1165 1367
1166 // Return the register containing the holder. 1368 // Return the register containing the holder.
1167 return reg; 1369 return reg;
1168 } 1370 }
1169 1371
1170 1372
1171 void StubCompiler::GenerateLoadField(JSObject* object, 1373 void StubCompiler::GenerateLoadField(Handle<JSObject> object,
1172 JSObject* holder, 1374 Handle<JSObject> holder,
1173 Register receiver, 1375 Register receiver,
1174 Register scratch1, 1376 Register scratch1,
1175 Register scratch2, 1377 Register scratch2,
1176 Register scratch3, 1378 Register scratch3,
1177 int index, 1379 int index,
1178 String* name, 1380 Handle<String> name,
1179 Label* miss) { 1381 Label* miss) {
1180 // Check that the receiver isn't a smi. 1382 // Check that the receiver isn't a smi.
1181 __ JumpIfSmi(receiver, miss); 1383 __ JumpIfSmi(receiver, miss);
1182 1384
1183 // Check that the maps haven't changed. 1385 // Check that the maps haven't changed.
1184 Register reg = 1386 Register reg = CheckPrototypes(
1185 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, 1387 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
1186 name, miss);
1187 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); 1388 GenerateFastPropertyLoad(masm(), r0, reg, holder, index);
1188 __ Ret(); 1389 __ Ret();
1189 } 1390 }
1190 1391
1191 1392
1192 void StubCompiler::GenerateLoadConstant(JSObject* object, 1393 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
1193 JSObject* holder, 1394 Handle<JSObject> holder,
1194 Register receiver, 1395 Register receiver,
1195 Register scratch1, 1396 Register scratch1,
1196 Register scratch2, 1397 Register scratch2,
1197 Register scratch3, 1398 Register scratch3,
1198 Object* value, 1399 Handle<Object> value,
1199 String* name, 1400 Handle<String> name,
1200 Label* miss) { 1401 Label* miss) {
1201 // Check that the receiver isn't a smi. 1402 // Check that the receiver isn't a smi.
1202 __ JumpIfSmi(receiver, miss); 1403 __ JumpIfSmi(receiver, miss);
1203 1404
1204 // Check that the maps haven't changed. 1405 // Check that the maps haven't changed.
1205 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, name, 1406 CheckPrototypes(
1206 miss); 1407 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
1207 1408
1208 // Return the constant value. 1409 // Return the constant value.
1209 __ mov(r0, Operand(Handle<Object>(value))); 1410 __ mov(r0, Operand(value));
1210 __ Ret(); 1411 __ Ret();
1211 } 1412 }
1212 1413
1213 1414
1214 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1415 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1215 JSObject* holder, 1416 JSObject* holder,
1216 Register receiver, 1417 Register receiver,
1217 Register name_reg, 1418 Register name_reg,
1218 Register scratch1, 1419 Register scratch1,
1219 Register scratch2, 1420 Register scratch2,
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 scratch2, 1559 scratch2,
1359 scratch3, 1560 scratch3,
1360 name, 1561 name,
1361 miss); 1562 miss);
1362 } 1563 }
1363 1564
1364 if (lookup->type() == FIELD) { 1565 if (lookup->type() == FIELD) {
1365 // We found FIELD property in prototype chain of interceptor's holder. 1566 // We found FIELD property in prototype chain of interceptor's holder.
1366 // Retrieve a field from field's holder. 1567 // Retrieve a field from field's holder.
1367 GenerateFastPropertyLoad(masm(), r0, holder_reg, 1568 GenerateFastPropertyLoad(masm(), r0, holder_reg,
1368 lookup->holder(), lookup->GetFieldIndex()); 1569 Handle<JSObject>(lookup->holder()),
1570 lookup->GetFieldIndex());
1369 __ Ret(); 1571 __ Ret();
1370 } else { 1572 } else {
1371 // We found CALLBACKS property in prototype chain of interceptor's 1573 // We found CALLBACKS property in prototype chain of interceptor's
1372 // holder. 1574 // holder.
1373 ASSERT(lookup->type() == CALLBACKS); 1575 ASSERT(lookup->type() == CALLBACKS);
1374 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1576 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
1375 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1577 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1376 ASSERT(callback != NULL); 1578 ASSERT(callback != NULL);
1377 ASSERT(callback->getter() != NULL); 1579 ASSERT(callback->getter() != NULL);
1378 1580
(...skipping 30 matching lines...) Expand all
1409 name_reg, interceptor_holder); 1611 name_reg, interceptor_holder);
1410 1612
1411 ExternalReference ref = 1613 ExternalReference ref =
1412 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), 1614 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
1413 masm()->isolate()); 1615 masm()->isolate());
1414 __ TailCallExternalReference(ref, 5, 1); 1616 __ TailCallExternalReference(ref, 5, 1);
1415 } 1617 }
1416 } 1618 }
1417 1619
1418 1620
1419 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1621 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1420 if (kind_ == Code::KEYED_CALL_IC) { 1622 if (kind_ == Code::KEYED_CALL_IC) {
1421 __ cmp(r2, Operand(Handle<String>(name))); 1623 __ cmp(r2, Operand(name));
1422 __ b(ne, miss); 1624 __ b(ne, miss);
1423 } 1625 }
1424 } 1626 }
1425 1627
1426 1628
1427 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1629 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1428 JSObject* holder, 1630 JSObject* holder,
1429 String* name, 1631 String* name,
1430 Label* miss) { 1632 Label* miss) {
1431 ASSERT(holder->IsGlobalObject()); 1633 ASSERT(holder->IsGlobalObject());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1673 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1472 __ cmp(r4, r3); 1674 __ cmp(r4, r3);
1473 __ b(ne, miss); 1675 __ b(ne, miss);
1474 } else { 1676 } else {
1475 __ cmp(r1, Operand(Handle<JSFunction>(function))); 1677 __ cmp(r1, Operand(Handle<JSFunction>(function)));
1476 __ b(ne, miss); 1678 __ b(ne, miss);
1477 } 1679 }
1478 } 1680 }
1479 1681
1480 1682
1481 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1683 void CallStubCompiler::GenerateMissBranch() {
1482 MaybeObject* maybe_obj = 1684 Handle<Code> code =
1483 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1685 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1484 kind_, 1686 kind_,
1485 extra_ic_state_); 1687 extra_state_);
1688 __ Jump(code, RelocInfo::CODE_TARGET);
1689 }
1690
1691
1692 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1693 // handlified.
1694 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1695 MaybeObject* maybe_obj =
1696 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1697 kind_,
1698 extra_state_);
1486 Object* obj; 1699 Object* obj;
1487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1700 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1488 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1701 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1489 return obj; 1702 return obj;
1490 } 1703 }
1491 1704
1492 1705
1493 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, 1706 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1494 JSObject* holder, 1707 Handle<JSObject> holder,
1495 int index, 1708 int index,
1496 String* name) { 1709 Handle<String> name) {
1497 // ----------- S t a t e ------------- 1710 // ----------- S t a t e -------------
1498 // -- r2 : name 1711 // -- r2 : name
1499 // -- lr : return address 1712 // -- lr : return address
1500 // ----------------------------------- 1713 // -----------------------------------
1501 Label miss; 1714 Label miss;
1502 1715
1503 GenerateNameCheck(name, &miss); 1716 GenerateNameCheck(name, &miss);
1504 1717
1505 const int argc = arguments().immediate(); 1718 const int argc = arguments().immediate();
1506 1719
1507 // Get the receiver of the function from the stack into r0. 1720 // Get the receiver of the function from the stack into r0.
1508 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 1721 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
1509 // Check that the receiver isn't a smi. 1722 // Check that the receiver isn't a smi.
1510 __ JumpIfSmi(r0, &miss); 1723 __ JumpIfSmi(r0, &miss);
1511 1724
1512 // Do the right check and compute the holder register. 1725 // Do the right check and compute the holder register.
1513 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); 1726 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss);
1514 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); 1727 GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
1515 1728
1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); 1729 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
1517 1730
1518 // Handle call cache miss. 1731 // Handle call cache miss.
1519 __ bind(&miss); 1732 __ bind(&miss);
1520 MaybeObject* maybe_result = GenerateMissBranch(); 1733 GenerateMissBranch();
1521 if (maybe_result->IsFailure()) return maybe_result;
1522 1734
1523 // Return the generated code. 1735 // Return the generated code.
1524 return GetCode(FIELD, name); 1736 return GetCode(FIELD, name);
1525 } 1737 }
1526 1738
1527 1739
1528 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1740 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
1529 JSObject* holder, 1741 JSObject* holder,
1530 JSGlobalPropertyCell* cell, 1742 JSGlobalPropertyCell* cell,
1531 JSFunction* function, 1743 JSFunction* function,
1532 String* name) { 1744 String* name) {
1533 // ----------- S t a t e ------------- 1745 // ----------- S t a t e -------------
1534 // -- r2 : name 1746 // -- r2 : name
1535 // -- lr : return address 1747 // -- lr : return address
1536 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1748 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1537 // -- ... 1749 // -- ...
1538 // -- sp[argc * 4] : receiver 1750 // -- sp[argc * 4] : receiver
1539 // ----------------------------------- 1751 // -----------------------------------
1540 1752
1541 // If object is not an array, bail out to regular call. 1753 // If object is not an array, bail out to regular call.
1542 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1754 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1543 1755
1544 Label miss; 1756 Label miss;
1545 1757
1546 GenerateNameCheck(name, &miss); 1758 GenerateNameCheck(Handle<String>(name), &miss);
1547 1759
1548 Register receiver = r1; 1760 Register receiver = r1;
1549 1761
1550 // Get the receiver from the stack 1762 // Get the receiver from the stack
1551 const int argc = arguments().immediate(); 1763 const int argc = arguments().immediate();
1552 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); 1764 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
1553 1765
1554 // Check that the receiver isn't a smi. 1766 // Check that the receiver isn't a smi.
1555 __ JumpIfSmi(receiver, &miss); 1767 __ JumpIfSmi(receiver, &miss);
1556 1768
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1824 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1613 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1825 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1614 1826
1615 // Check for a smi. 1827 // Check for a smi.
1616 __ Drop(argc + 1); 1828 __ Drop(argc + 1);
1617 __ Ret(); 1829 __ Ret();
1618 1830
1619 __ bind(&with_write_barrier); 1831 __ bind(&with_write_barrier);
1620 1832
1621 __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1833 __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset));
1622 __ CheckFastSmiOnlyElements(r6, r6, &call_builtin); 1834 __ CheckFastObjectElements(r6, r6, &call_builtin);
1623 1835
1624 // Save new length. 1836 // Save new length.
1625 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1837 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1626 1838
1627 // Push the element. 1839 // Push the element.
1628 // We may need a register containing the address end_elements below, 1840 // We may need a register containing the address end_elements below,
1629 // so write back the value in end_elements. 1841 // so write back the value in end_elements.
1630 __ add(end_elements, elements, 1842 __ add(end_elements, elements,
1631 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); 1843 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
1632 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1844 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 } 1914 }
1703 __ bind(&call_builtin); 1915 __ bind(&call_builtin);
1704 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 1916 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
1705 masm()->isolate()), 1917 masm()->isolate()),
1706 argc + 1, 1918 argc + 1,
1707 1); 1919 1);
1708 } 1920 }
1709 1921
1710 // Handle call cache miss. 1922 // Handle call cache miss.
1711 __ bind(&miss); 1923 __ bind(&miss);
1712 MaybeObject* maybe_result = GenerateMissBranch(); 1924 MaybeObject* maybe_result = TryGenerateMissBranch();
1713 if (maybe_result->IsFailure()) return maybe_result; 1925 if (maybe_result->IsFailure()) return maybe_result;
1714 1926
1715 // Return the generated code. 1927 // Return the generated code.
1716 return GetCode(function); 1928 return TryGetCode(function);
1717 } 1929 }
1718 1930
1719 1931
1720 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1932 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1721 JSObject* holder, 1933 JSObject* holder,
1722 JSGlobalPropertyCell* cell, 1934 JSGlobalPropertyCell* cell,
1723 JSFunction* function, 1935 JSFunction* function,
1724 String* name) { 1936 String* name) {
1725 // ----------- S t a t e ------------- 1937 // ----------- S t a t e -------------
1726 // -- r2 : name 1938 // -- r2 : name
1727 // -- lr : return address 1939 // -- lr : return address
1728 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1940 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1729 // -- ... 1941 // -- ...
1730 // -- sp[argc * 4] : receiver 1942 // -- sp[argc * 4] : receiver
1731 // ----------------------------------- 1943 // -----------------------------------
1732 1944
1733 // If object is not an array, bail out to regular call. 1945 // If object is not an array, bail out to regular call.
1734 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1946 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1735 1947
1736 Label miss, return_undefined, call_builtin; 1948 Label miss, return_undefined, call_builtin;
1737 1949
1738 Register receiver = r1; 1950 Register receiver = r1;
1739 Register elements = r3; 1951 Register elements = r3;
1740 1952
1741 GenerateNameCheck(name, &miss); 1953 GenerateNameCheck(Handle<String>(name), &miss);
1742 1954
1743 // Get the receiver from the stack 1955 // Get the receiver from the stack
1744 const int argc = arguments().immediate(); 1956 const int argc = arguments().immediate();
1745 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); 1957 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
1746 1958
1747 // Check that the receiver isn't a smi. 1959 // Check that the receiver isn't a smi.
1748 __ JumpIfSmi(receiver, &miss); 1960 __ JumpIfSmi(receiver, &miss);
1749 1961
1750 // Check that the maps haven't changed. 1962 // Check that the maps haven't changed.
1751 CheckPrototypes(JSObject::cast(object), 1963 CheckPrototypes(JSObject::cast(object),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 __ Ret(); 2003 __ Ret();
1792 2004
1793 __ bind(&call_builtin); 2005 __ bind(&call_builtin);
1794 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, 2006 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop,
1795 masm()->isolate()), 2007 masm()->isolate()),
1796 argc + 1, 2008 argc + 1,
1797 1); 2009 1);
1798 2010
1799 // Handle call cache miss. 2011 // Handle call cache miss.
1800 __ bind(&miss); 2012 __ bind(&miss);
1801 MaybeObject* maybe_result = GenerateMissBranch(); 2013 MaybeObject* maybe_result = TryGenerateMissBranch();
1802 if (maybe_result->IsFailure()) return maybe_result; 2014 if (maybe_result->IsFailure()) return maybe_result;
1803 2015
1804 // Return the generated code. 2016 // Return the generated code.
1805 return GetCode(function); 2017 return TryGetCode(function);
1806 } 2018 }
1807 2019
1808 2020
1809 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 2021 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1810 Object* object, 2022 Object* object,
1811 JSObject* holder, 2023 JSObject* holder,
1812 JSGlobalPropertyCell* cell, 2024 JSGlobalPropertyCell* cell,
1813 JSFunction* function, 2025 JSFunction* function,
1814 String* name) { 2026 String* name) {
1815 // ----------- S t a t e ------------- 2027 // ----------- S t a t e -------------
1816 // -- r2 : function name 2028 // -- r2 : function name
1817 // -- lr : return address 2029 // -- lr : return address
1818 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2030 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1819 // -- ... 2031 // -- ...
1820 // -- sp[argc * 4] : receiver 2032 // -- sp[argc * 4] : receiver
1821 // ----------------------------------- 2033 // -----------------------------------
1822 2034
1823 // If object is not a string, bail out to regular call. 2035 // If object is not a string, bail out to regular call.
1824 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 2036 if (!object->IsString() || cell != NULL) return heap()->undefined_value();
1825 2037
1826 const int argc = arguments().immediate(); 2038 const int argc = arguments().immediate();
1827 2039
1828 Label miss; 2040 Label miss;
1829 Label name_miss; 2041 Label name_miss;
1830 Label index_out_of_range; 2042 Label index_out_of_range;
1831 Label* index_out_of_range_label = &index_out_of_range; 2043 Label* index_out_of_range_label = &index_out_of_range;
1832 2044
1833 if (kind_ == Code::CALL_IC && 2045 if (kind_ == Code::CALL_IC &&
1834 (CallICBase::StringStubState::decode(extra_ic_state_) == 2046 (CallICBase::StringStubState::decode(extra_state_) ==
1835 DEFAULT_STRING_STUB)) { 2047 DEFAULT_STRING_STUB)) {
1836 index_out_of_range_label = &miss; 2048 index_out_of_range_label = &miss;
1837 } 2049 }
1838 2050
1839 GenerateNameCheck(name, &name_miss); 2051 GenerateNameCheck(Handle<String>(name), &name_miss);
1840 2052
1841 // Check that the maps starting from the prototype haven't changed. 2053 // Check that the maps starting from the prototype haven't changed.
1842 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2054 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1843 Context::STRING_FUNCTION_INDEX, 2055 Context::STRING_FUNCTION_INDEX,
1844 r0, 2056 r0,
1845 &miss); 2057 &miss);
1846 ASSERT(object != holder); 2058 ASSERT(object != holder);
1847 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, 2059 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder,
1848 r1, r3, r4, name, &miss); 2060 r1, r3, r4, name, &miss);
1849 2061
(...skipping 27 matching lines...) Expand all
1877 __ bind(&index_out_of_range); 2089 __ bind(&index_out_of_range);
1878 __ LoadRoot(r0, Heap::kNanValueRootIndex); 2090 __ LoadRoot(r0, Heap::kNanValueRootIndex);
1879 __ Drop(argc + 1); 2091 __ Drop(argc + 1);
1880 __ Ret(); 2092 __ Ret();
1881 } 2093 }
1882 2094
1883 __ bind(&miss); 2095 __ bind(&miss);
1884 // Restore function name in r2. 2096 // Restore function name in r2.
1885 __ Move(r2, Handle<String>(name)); 2097 __ Move(r2, Handle<String>(name));
1886 __ bind(&name_miss); 2098 __ bind(&name_miss);
1887 MaybeObject* maybe_result = GenerateMissBranch(); 2099 MaybeObject* maybe_result = TryGenerateMissBranch();
1888 if (maybe_result->IsFailure()) return maybe_result; 2100 if (maybe_result->IsFailure()) return maybe_result;
1889 2101
1890 // Return the generated code. 2102 // Return the generated code.
1891 return GetCode(function); 2103 return TryGetCode(function);
1892 } 2104 }
1893 2105
1894 2106
1895 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 2107 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
1896 Object* object, 2108 Object* object,
1897 JSObject* holder, 2109 JSObject* holder,
1898 JSGlobalPropertyCell* cell, 2110 JSGlobalPropertyCell* cell,
1899 JSFunction* function, 2111 JSFunction* function,
1900 String* name) { 2112 String* name) {
1901 // ----------- S t a t e ------------- 2113 // ----------- S t a t e -------------
1902 // -- r2 : function name 2114 // -- r2 : function name
1903 // -- lr : return address 2115 // -- lr : return address
1904 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2116 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1905 // -- ... 2117 // -- ...
1906 // -- sp[argc * 4] : receiver 2118 // -- sp[argc * 4] : receiver
1907 // ----------------------------------- 2119 // -----------------------------------
1908 2120
1909 // If object is not a string, bail out to regular call. 2121 // If object is not a string, bail out to regular call.
1910 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 2122 if (!object->IsString() || cell != NULL) return heap()->undefined_value();
1911 2123
1912 const int argc = arguments().immediate(); 2124 const int argc = arguments().immediate();
1913 2125
1914 Label miss; 2126 Label miss;
1915 Label name_miss; 2127 Label name_miss;
1916 Label index_out_of_range; 2128 Label index_out_of_range;
1917 Label* index_out_of_range_label = &index_out_of_range; 2129 Label* index_out_of_range_label = &index_out_of_range;
1918 2130
1919 if (kind_ == Code::CALL_IC && 2131 if (kind_ == Code::CALL_IC &&
1920 (CallICBase::StringStubState::decode(extra_ic_state_) == 2132 (CallICBase::StringStubState::decode(extra_state_) ==
1921 DEFAULT_STRING_STUB)) { 2133 DEFAULT_STRING_STUB)) {
1922 index_out_of_range_label = &miss; 2134 index_out_of_range_label = &miss;
1923 } 2135 }
1924 2136
1925 GenerateNameCheck(name, &name_miss); 2137 GenerateNameCheck(Handle<String>(name), &name_miss);
1926 2138
1927 // Check that the maps starting from the prototype haven't changed. 2139 // Check that the maps starting from the prototype haven't changed.
1928 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2140 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1929 Context::STRING_FUNCTION_INDEX, 2141 Context::STRING_FUNCTION_INDEX,
1930 r0, 2142 r0,
1931 &miss); 2143 &miss);
1932 ASSERT(object != holder); 2144 ASSERT(object != holder);
1933 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, 2145 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder,
1934 r1, r3, r4, name, &miss); 2146 r1, r3, r4, name, &miss);
1935 2147
(...skipping 29 matching lines...) Expand all
1965 __ bind(&index_out_of_range); 2177 __ bind(&index_out_of_range);
1966 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); 2178 __ LoadRoot(r0, Heap::kEmptyStringRootIndex);
1967 __ Drop(argc + 1); 2179 __ Drop(argc + 1);
1968 __ Ret(); 2180 __ Ret();
1969 } 2181 }
1970 2182
1971 __ bind(&miss); 2183 __ bind(&miss);
1972 // Restore function name in r2. 2184 // Restore function name in r2.
1973 __ Move(r2, Handle<String>(name)); 2185 __ Move(r2, Handle<String>(name));
1974 __ bind(&name_miss); 2186 __ bind(&name_miss);
1975 MaybeObject* maybe_result = GenerateMissBranch(); 2187 MaybeObject* maybe_result = TryGenerateMissBranch();
1976 if (maybe_result->IsFailure()) return maybe_result; 2188 if (maybe_result->IsFailure()) return maybe_result;
1977 2189
1978 // Return the generated code. 2190 // Return the generated code.
1979 return GetCode(function); 2191 return TryGetCode(function);
1980 } 2192 }
1981 2193
1982 2194
1983 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 2195 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
1984 Object* object, 2196 Object* object,
1985 JSObject* holder, 2197 JSObject* holder,
1986 JSGlobalPropertyCell* cell, 2198 JSGlobalPropertyCell* cell,
1987 JSFunction* function, 2199 JSFunction* function,
1988 String* name) { 2200 String* name) {
1989 // ----------- S t a t e ------------- 2201 // ----------- S t a t e -------------
1990 // -- r2 : function name 2202 // -- r2 : function name
1991 // -- lr : return address 2203 // -- lr : return address
1992 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2204 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1993 // -- ... 2205 // -- ...
1994 // -- sp[argc * 4] : receiver 2206 // -- sp[argc * 4] : receiver
1995 // ----------------------------------- 2207 // -----------------------------------
1996 2208
1997 const int argc = arguments().immediate(); 2209 const int argc = arguments().immediate();
1998 2210
1999 // If the object is not a JSObject or we got an unexpected number of 2211 // If the object is not a JSObject or we got an unexpected number of
2000 // arguments, bail out to the regular call. 2212 // arguments, bail out to the regular call.
2001 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2213 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2002 2214
2003 Label miss; 2215 Label miss;
2004 GenerateNameCheck(name, &miss); 2216 GenerateNameCheck(Handle<String>(name), &miss);
2005 2217
2006 if (cell == NULL) { 2218 if (cell == NULL) {
2007 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2219 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2008 2220
2009 STATIC_ASSERT(kSmiTag == 0); 2221 STATIC_ASSERT(kSmiTag == 0);
2010 __ JumpIfSmi(r1, &miss); 2222 __ JumpIfSmi(r1, &miss);
2011 2223
2012 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 2224 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
2013 &miss); 2225 &miss);
2014 } else { 2226 } else {
(...skipping 22 matching lines...) Expand all
2037 StubRuntimeCallHelper call_helper; 2249 StubRuntimeCallHelper call_helper;
2038 char_from_code_generator.GenerateSlow(masm(), call_helper); 2250 char_from_code_generator.GenerateSlow(masm(), call_helper);
2039 2251
2040 // Tail call the full function. We do not have to patch the receiver 2252 // Tail call the full function. We do not have to patch the receiver
2041 // because the function makes no use of it. 2253 // because the function makes no use of it.
2042 __ bind(&slow); 2254 __ bind(&slow);
2043 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2255 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2044 2256
2045 __ bind(&miss); 2257 __ bind(&miss);
2046 // r2: function name. 2258 // r2: function name.
2047 MaybeObject* maybe_result = GenerateMissBranch(); 2259 MaybeObject* maybe_result = TryGenerateMissBranch();
2048 if (maybe_result->IsFailure()) return maybe_result; 2260 if (maybe_result->IsFailure()) return maybe_result;
2049 2261
2050 // Return the generated code. 2262 // Return the generated code.
2051 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2263 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2052 } 2264 }
2053 2265
2054 2266
2055 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 2267 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
2056 JSObject* holder, 2268 JSObject* holder,
2057 JSGlobalPropertyCell* cell, 2269 JSGlobalPropertyCell* cell,
2058 JSFunction* function, 2270 JSFunction* function,
2059 String* name) { 2271 String* name) {
2060 // ----------- S t a t e ------------- 2272 // ----------- S t a t e -------------
2061 // -- r2 : function name 2273 // -- r2 : function name
2062 // -- lr : return address 2274 // -- lr : return address
2063 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2275 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2064 // -- ... 2276 // -- ...
2065 // -- sp[argc * 4] : receiver 2277 // -- sp[argc * 4] : receiver
2066 // ----------------------------------- 2278 // -----------------------------------
2067 2279
2068 if (!CpuFeatures::IsSupported(VFP3)) { 2280 if (!CpuFeatures::IsSupported(VFP3)) {
2069 return heap()->undefined_value(); 2281 return heap()->undefined_value();
2070 } 2282 }
2071 2283
2072 CpuFeatures::Scope scope_vfp3(VFP3); 2284 CpuFeatures::Scope scope_vfp3(VFP3);
2073 2285
2074 const int argc = arguments().immediate(); 2286 const int argc = arguments().immediate();
2075 2287
2076 // If the object is not a JSObject or we got an unexpected number of 2288 // If the object is not a JSObject or we got an unexpected number of
2077 // arguments, bail out to the regular call. 2289 // arguments, bail out to the regular call.
2078 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2290 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2079 2291
2080 Label miss, slow; 2292 Label miss, slow;
2081 GenerateNameCheck(name, &miss); 2293 GenerateNameCheck(Handle<String>(name), &miss);
2082 2294
2083 if (cell == NULL) { 2295 if (cell == NULL) {
2084 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2296 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2085 2297
2086 STATIC_ASSERT(kSmiTag == 0); 2298 STATIC_ASSERT(kSmiTag == 0);
2087 __ JumpIfSmi(r1, &miss); 2299 __ JumpIfSmi(r1, &miss);
2088 2300
2089 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 2301 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
2090 &miss); 2302 &miss);
2091 } else { 2303 } else {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 // Restore FPCSR and fall to slow case. 2397 // Restore FPCSR and fall to slow case.
2186 __ vmsr(r3); 2398 __ vmsr(r3);
2187 2399
2188 __ bind(&slow); 2400 __ bind(&slow);
2189 // Tail call the full function. We do not have to patch the receiver 2401 // Tail call the full function. We do not have to patch the receiver
2190 // because the function makes no use of it. 2402 // because the function makes no use of it.
2191 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2403 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2192 2404
2193 __ bind(&miss); 2405 __ bind(&miss);
2194 // r2: function name. 2406 // r2: function name.
2195 MaybeObject* maybe_result = GenerateMissBranch(); 2407 MaybeObject* maybe_result = TryGenerateMissBranch();
2196 if (maybe_result->IsFailure()) return maybe_result; 2408 if (maybe_result->IsFailure()) return maybe_result;
2197 2409
2198 // Return the generated code. 2410 // Return the generated code.
2199 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2411 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2200 } 2412 }
2201 2413
2202 2414
2203 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, 2415 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
2204 JSObject* holder, 2416 JSObject* holder,
2205 JSGlobalPropertyCell* cell, 2417 JSGlobalPropertyCell* cell,
2206 JSFunction* function, 2418 JSFunction* function,
2207 String* name) { 2419 String* name) {
2208 // ----------- S t a t e ------------- 2420 // ----------- S t a t e -------------
2209 // -- r2 : function name 2421 // -- r2 : function name
2210 // -- lr : return address 2422 // -- lr : return address
2211 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2423 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2212 // -- ... 2424 // -- ...
2213 // -- sp[argc * 4] : receiver 2425 // -- sp[argc * 4] : receiver
2214 // ----------------------------------- 2426 // -----------------------------------
2215 2427
2216 const int argc = arguments().immediate(); 2428 const int argc = arguments().immediate();
2217 2429
2218 // If the object is not a JSObject or we got an unexpected number of 2430 // If the object is not a JSObject or we got an unexpected number of
2219 // arguments, bail out to the regular call. 2431 // arguments, bail out to the regular call.
2220 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2432 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2221 2433
2222 Label miss; 2434 Label miss;
2223 GenerateNameCheck(name, &miss); 2435 GenerateNameCheck(Handle<String>(name), &miss);
2224 2436
2225 if (cell == NULL) { 2437 if (cell == NULL) {
2226 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2438 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2227 2439
2228 STATIC_ASSERT(kSmiTag == 0); 2440 STATIC_ASSERT(kSmiTag == 0);
2229 __ JumpIfSmi(r1, &miss); 2441 __ JumpIfSmi(r1, &miss);
2230 2442
2231 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 2443 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
2232 &miss); 2444 &miss);
2233 } else { 2445 } else {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 __ Drop(argc + 1); 2498 __ Drop(argc + 1);
2287 __ Ret(); 2499 __ Ret();
2288 2500
2289 // Tail call the full function. We do not have to patch the receiver 2501 // Tail call the full function. We do not have to patch the receiver
2290 // because the function makes no use of it. 2502 // because the function makes no use of it.
2291 __ bind(&slow); 2503 __ bind(&slow);
2292 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2504 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2293 2505
2294 __ bind(&miss); 2506 __ bind(&miss);
2295 // r2: function name. 2507 // r2: function name.
2296 MaybeObject* maybe_result = GenerateMissBranch(); 2508 MaybeObject* maybe_result = TryGenerateMissBranch();
2297 if (maybe_result->IsFailure()) return maybe_result; 2509 if (maybe_result->IsFailure()) return maybe_result;
2298 2510
2299 // Return the generated code. 2511 // Return the generated code.
2300 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2512 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2301 } 2513 }
2302 2514
2303 2515
2304 MaybeObject* CallStubCompiler::CompileFastApiCall( 2516 MaybeObject* CallStubCompiler::CompileFastApiCall(
2305 const CallOptimization& optimization, 2517 const CallOptimization& optimization,
2306 Object* object, 2518 Object* object,
2307 JSObject* holder, 2519 JSObject* holder,
2308 JSGlobalPropertyCell* cell, 2520 JSGlobalPropertyCell* cell,
2309 JSFunction* function, 2521 JSFunction* function,
2310 String* name) { 2522 String* name) {
2311 Counters* counters = isolate()->counters(); 2523 Counters* counters = isolate()->counters();
2312 2524
2313 ASSERT(optimization.is_simple_api_call()); 2525 ASSERT(optimization.is_simple_api_call());
2314 // Bail out if object is a global object as we don't want to 2526 // Bail out if object is a global object as we don't want to
2315 // repatch it to global receiver. 2527 // repatch it to global receiver.
2316 if (object->IsGlobalObject()) return heap()->undefined_value(); 2528 if (object->IsGlobalObject()) return heap()->undefined_value();
2317 if (cell != NULL) return heap()->undefined_value(); 2529 if (cell != NULL) return heap()->undefined_value();
2318 if (!object->IsJSObject()) return heap()->undefined_value(); 2530 if (!object->IsJSObject()) return heap()->undefined_value();
2319 int depth = optimization.GetPrototypeDepthOfExpectedType( 2531 int depth = optimization.GetPrototypeDepthOfExpectedType(
2320 JSObject::cast(object), holder); 2532 JSObject::cast(object), holder);
2321 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2533 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2322 2534
2323 Label miss, miss_before_stack_reserved; 2535 Label miss, miss_before_stack_reserved;
2324 2536
2325 GenerateNameCheck(name, &miss_before_stack_reserved); 2537 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
2326 2538
2327 // Get the receiver from the stack. 2539 // Get the receiver from the stack.
2328 const int argc = arguments().immediate(); 2540 const int argc = arguments().immediate();
2329 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2541 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2330 2542
2331 // Check that the receiver isn't a smi. 2543 // Check that the receiver isn't a smi.
2332 __ JumpIfSmi(r1, &miss_before_stack_reserved); 2544 __ JumpIfSmi(r1, &miss_before_stack_reserved);
2333 2545
2334 __ IncrementCounter(counters->call_const(), 1, r0, r3); 2546 __ IncrementCounter(counters->call_const(), 1, r0, r3);
2335 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); 2547 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3);
2336 2548
2337 ReserveSpaceForFastApiCall(masm(), r0); 2549 ReserveSpaceForFastApiCall(masm(), r0);
2338 2550
2339 // Check that the maps haven't changed and find a Holder as a side effect. 2551 // Check that the maps haven't changed and find a Holder as a side effect.
2340 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 2552 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
2341 depth, &miss); 2553 depth, &miss);
2342 2554
2343 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); 2555 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc);
2344 if (result->IsFailure()) return result; 2556 if (result->IsFailure()) return result;
2345 2557
2346 __ bind(&miss); 2558 __ bind(&miss);
2347 FreeSpaceForFastApiCall(masm()); 2559 FreeSpaceForFastApiCall(masm());
2348 2560
2349 __ bind(&miss_before_stack_reserved); 2561 __ bind(&miss_before_stack_reserved);
2350 MaybeObject* maybe_result = GenerateMissBranch(); 2562 MaybeObject* maybe_result = TryGenerateMissBranch();
2351 if (maybe_result->IsFailure()) return maybe_result; 2563 if (maybe_result->IsFailure()) return maybe_result;
2352 2564
2353 // Return the generated code. 2565 // Return the generated code.
2354 return GetCode(function); 2566 return TryGetCode(function);
2355 } 2567 }
2356 2568
2357 2569
2358 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2570 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
2359 JSObject* holder, 2571 JSObject* holder,
2360 JSFunction* function, 2572 JSFunction* function,
2361 String* name, 2573 String* name,
2362 CheckType check) { 2574 CheckType check) {
2363 // ----------- S t a t e ------------- 2575 // ----------- S t a t e -------------
2364 // -- r2 : name 2576 // -- r2 : name
2365 // -- lr : return address 2577 // -- lr : return address
2366 // ----------------------------------- 2578 // -----------------------------------
2367 if (HasCustomCallGenerator(function)) { 2579 if (HasCustomCallGenerator(function)) {
2368 MaybeObject* maybe_result = CompileCustomCall( 2580 MaybeObject* maybe_result = CompileCustomCall(
2369 object, holder, NULL, function, name); 2581 object, holder, NULL, function, name);
2370 Object* result; 2582 Object* result;
2371 if (!maybe_result->ToObject(&result)) return maybe_result; 2583 if (!maybe_result->ToObject(&result)) return maybe_result;
2372 // undefined means bail out to regular compiler. 2584 // undefined means bail out to regular compiler.
2373 if (!result->IsUndefined()) return result; 2585 if (!result->IsUndefined()) return result;
2374 } 2586 }
2375 2587
2376 Label miss; 2588 Label miss;
2377 2589
2378 GenerateNameCheck(name, &miss); 2590 GenerateNameCheck(Handle<String>(name), &miss);
2379 2591
2380 // Get the receiver from the stack 2592 // Get the receiver from the stack
2381 const int argc = arguments().immediate(); 2593 const int argc = arguments().immediate();
2382 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2594 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2383 2595
2384 // Check that the receiver isn't a smi. 2596 // Check that the receiver isn't a smi.
2385 if (check != NUMBER_CHECK) { 2597 if (check != NUMBER_CHECK) {
2386 __ JumpIfSmi(r1, &miss); 2598 __ JumpIfSmi(r1, &miss);
2387 } 2599 }
2388 2600
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2467 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, 2679 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3,
2468 r1, r4, name, &miss); 2680 r1, r4, name, &miss);
2469 } 2681 }
2470 break; 2682 break;
2471 } 2683 }
2472 2684
2473 default: 2685 default:
2474 UNREACHABLE(); 2686 UNREACHABLE();
2475 } 2687 }
2476 2688
2477 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2689 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2478 ? CALL_AS_FUNCTION 2690 ? CALL_AS_FUNCTION
2479 : CALL_AS_METHOD; 2691 : CALL_AS_METHOD;
2480 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); 2692 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
2481 2693
2482 // Handle call cache miss. 2694 // Handle call cache miss.
2483 __ bind(&miss); 2695 __ bind(&miss);
2484 MaybeObject* maybe_result = GenerateMissBranch(); 2696 MaybeObject* maybe_result = TryGenerateMissBranch();
2485 if (maybe_result->IsFailure()) return maybe_result; 2697 if (maybe_result->IsFailure()) return maybe_result;
2486 2698
2487 // Return the generated code. 2699 // Return the generated code.
2488 return GetCode(function); 2700 return TryGetCode(function);
2489 } 2701 }
2490 2702
2491 2703
2492 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2704 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
2493 JSObject* holder, 2705 JSObject* holder,
2494 String* name) { 2706 String* name) {
2495 // ----------- S t a t e ------------- 2707 // ----------- S t a t e -------------
2496 // -- r2 : name 2708 // -- r2 : name
2497 // -- lr : return address 2709 // -- lr : return address
2498 // ----------------------------------- 2710 // -----------------------------------
2499 2711
2500 Label miss; 2712 Label miss;
2501 2713
2502 GenerateNameCheck(name, &miss); 2714 GenerateNameCheck(Handle<String>(name), &miss);
2503 2715
2504 // Get the number of arguments. 2716 // Get the number of arguments.
2505 const int argc = arguments().immediate(); 2717 const int argc = arguments().immediate();
2506 2718
2507 LookupResult lookup; 2719 LookupResult lookup(isolate());
2508 LookupPostInterceptor(holder, name, &lookup); 2720 LookupPostInterceptor(holder, name, &lookup);
2509 2721
2510 // Get the receiver from the stack. 2722 // Get the receiver from the stack.
2511 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2723 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2512 2724
2513 CallInterceptorCompiler compiler(this, arguments(), r2, extra_ic_state_); 2725 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_);
2514 MaybeObject* result = compiler.Compile(masm(), 2726 MaybeObject* result = compiler.Compile(masm(),
2515 object, 2727 object,
2516 holder, 2728 holder,
2517 name, 2729 name,
2518 &lookup, 2730 &lookup,
2519 r1, 2731 r1,
2520 r3, 2732 r3,
2521 r4, 2733 r4,
2522 r0, 2734 r0,
2523 &miss); 2735 &miss);
2524 if (result->IsFailure()) { 2736 if (result->IsFailure()) {
2525 return result; 2737 return result;
2526 } 2738 }
2527 2739
2528 // Move returned value, the function to call, to r1. 2740 // Move returned value, the function to call, to r1.
2529 __ mov(r1, r0); 2741 __ mov(r1, r0);
2530 // Restore receiver. 2742 // Restore receiver.
2531 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 2743 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
2532 2744
2533 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); 2745 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss,
2746 extra_state_);
2534 2747
2535 // Handle call cache miss. 2748 // Handle call cache miss.
2536 __ bind(&miss); 2749 __ bind(&miss);
2537 MaybeObject* maybe_result = GenerateMissBranch(); 2750 MaybeObject* maybe_result = TryGenerateMissBranch();
2538 if (maybe_result->IsFailure()) return maybe_result; 2751 if (maybe_result->IsFailure()) return maybe_result;
2539 2752
2540 // Return the generated code. 2753 // Return the generated code.
2541 return GetCode(INTERCEPTOR, name); 2754 return TryGetCode(INTERCEPTOR, name);
2542 } 2755 }
2543 2756
2544 2757
2545 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, 2758 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
2546 GlobalObject* holder, 2759 GlobalObject* holder,
2547 JSGlobalPropertyCell* cell, 2760 JSGlobalPropertyCell* cell,
2548 JSFunction* function, 2761 JSFunction* function,
2549 String* name) { 2762 String* name) {
2550 // ----------- S t a t e ------------- 2763 // ----------- S t a t e -------------
2551 // -- r2 : name 2764 // -- r2 : name
2552 // -- lr : return address 2765 // -- lr : return address
2553 // ----------------------------------- 2766 // -----------------------------------
2554 2767
2555 if (HasCustomCallGenerator(function)) { 2768 if (HasCustomCallGenerator(function)) {
2556 MaybeObject* maybe_result = CompileCustomCall( 2769 MaybeObject* maybe_result = CompileCustomCall(
2557 object, holder, cell, function, name); 2770 object, holder, cell, function, name);
2558 Object* result; 2771 Object* result;
2559 if (!maybe_result->ToObject(&result)) return maybe_result; 2772 if (!maybe_result->ToObject(&result)) return maybe_result;
2560 // undefined means bail out to regular compiler. 2773 // undefined means bail out to regular compiler.
2561 if (!result->IsUndefined()) return result; 2774 if (!result->IsUndefined()) return result;
2562 } 2775 }
2563 2776
2564 Label miss; 2777 Label miss;
2565 2778
2566 GenerateNameCheck(name, &miss); 2779 GenerateNameCheck(Handle<String>(name), &miss);
2567 2780
2568 // Get the number of arguments. 2781 // Get the number of arguments.
2569 const int argc = arguments().immediate(); 2782 const int argc = arguments().immediate();
2570 2783
2571 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2784 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2572 2785
2573 GenerateLoadFunctionFromCell(cell, function, &miss); 2786 GenerateLoadFunctionFromCell(cell, function, &miss);
2574 2787
2575 // Patch the receiver on the stack with the global proxy if 2788 // Patch the receiver on the stack with the global proxy if
2576 // necessary. 2789 // necessary.
2577 if (object->IsGlobalObject()) { 2790 if (object->IsGlobalObject()) {
2578 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); 2791 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
2579 __ str(r3, MemOperand(sp, argc * kPointerSize)); 2792 __ str(r3, MemOperand(sp, argc * kPointerSize));
2580 } 2793 }
2581 2794
2582 // Setup the context (function already in r1). 2795 // Setup the context (function already in r1).
2583 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 2796 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2584 2797
2585 // Jump to the cached code (tail call). 2798 // Jump to the cached code (tail call).
2586 Counters* counters = masm()->isolate()->counters(); 2799 Counters* counters = masm()->isolate()->counters();
2587 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); 2800 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
2588 ASSERT(function->is_compiled());
2589 Handle<Code> code(function->code()); 2801 Handle<Code> code(function->code());
2590 ParameterCount expected(function->shared()->formal_parameter_count()); 2802 ParameterCount expected(function->shared()->formal_parameter_count());
2591 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2803 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2592 ? CALL_AS_FUNCTION 2804 ? CALL_AS_FUNCTION
2593 : CALL_AS_METHOD; 2805 : CALL_AS_METHOD;
2594 if (V8::UseCrankshaft()) { 2806 // We call indirectly through the code field in the function to
2595 // TODO(kasperl): For now, we always call indirectly through the 2807 // allow recompilation to take effect without changing any of the
2596 // code field in the function to allow recompilation to take effect 2808 // call sites.
2597 // without changing any of the call sites. 2809 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2598 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 2810 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION,
2599 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, 2811 NullCallWrapper(), call_kind);
2600 NullCallWrapper(), call_kind);
2601 } else {
2602 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET,
2603 JUMP_FUNCTION, call_kind);
2604 }
2605 2812
2606 // Handle call cache miss. 2813 // Handle call cache miss.
2607 __ bind(&miss); 2814 __ bind(&miss);
2608 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); 2815 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3);
2609 MaybeObject* maybe_result = GenerateMissBranch(); 2816 MaybeObject* maybe_result = TryGenerateMissBranch();
2610 if (maybe_result->IsFailure()) return maybe_result; 2817 if (maybe_result->IsFailure()) return maybe_result;
2611 2818
2612 // Return the generated code. 2819 // Return the generated code.
2613 return GetCode(NORMAL, name); 2820 return TryGetCode(NORMAL, name);
2614 } 2821 }
2615 2822
2616 2823
2617 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, 2824 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2618 int index, 2825 int index,
2619 Map* transition, 2826 Handle<Map> transition,
2620 String* name) { 2827 Handle<String> name) {
2621 // ----------- S t a t e ------------- 2828 // ----------- S t a t e -------------
2622 // -- r0 : value 2829 // -- r0 : value
2623 // -- r1 : receiver 2830 // -- r1 : receiver
2624 // -- r2 : name 2831 // -- r2 : name
2625 // -- lr : return address 2832 // -- lr : return address
2626 // ----------------------------------- 2833 // -----------------------------------
2627 Label miss; 2834 Label miss;
2628 2835
2629 GenerateStoreField(masm(), 2836 GenerateStoreField(masm(), object, index, transition, r1, r2, r3, &miss);
2630 object,
2631 index,
2632 transition,
2633 r1, r2, r3,
2634 &miss);
2635 __ bind(&miss); 2837 __ bind(&miss);
2636 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2838 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2637 __ Jump(ic, RelocInfo::CODE_TARGET); 2839 __ Jump(ic, RelocInfo::CODE_TARGET);
2638 2840
2639 // Return the generated code. 2841 // Return the generated code.
2640 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2842 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2641 } 2843 }
2642 2844
2643 2845
2644 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2846 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2645 AccessorInfo* callback, 2847 Handle<JSObject> object,
2646 String* name) { 2848 Handle<AccessorInfo> callback,
2849 Handle<String> name) {
2647 // ----------- S t a t e ------------- 2850 // ----------- S t a t e -------------
2648 // -- r0 : value 2851 // -- r0 : value
2649 // -- r1 : receiver 2852 // -- r1 : receiver
2650 // -- r2 : name 2853 // -- r2 : name
2651 // -- lr : return address 2854 // -- lr : return address
2652 // ----------------------------------- 2855 // -----------------------------------
2653 Label miss; 2856 Label miss;
2654 2857
2655 // Check that the object isn't a smi. 2858 // Check that the object isn't a smi.
2656 __ JumpIfSmi(r1, &miss); 2859 __ JumpIfSmi(r1, &miss);
2657 2860
2658 // Check that the map of the object hasn't changed. 2861 // Check that the map of the object hasn't changed.
2659 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); 2862 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
2660 __ cmp(r3, Operand(Handle<Map>(object->map()))); 2863 __ cmp(r3, Operand(Handle<Map>(object->map())));
2661 __ b(ne, &miss); 2864 __ b(ne, &miss);
2662 2865
2663 // Perform global security token check if needed. 2866 // Perform global security token check if needed.
2664 if (object->IsJSGlobalProxy()) { 2867 if (object->IsJSGlobalProxy()) {
2665 __ CheckAccessGlobalProxy(r1, r3, &miss); 2868 __ CheckAccessGlobalProxy(r1, r3, &miss);
2666 } 2869 }
2667 2870
2668 // Stub never generated for non-global objects that require access 2871 // Stub never generated for non-global objects that require access
2669 // checks. 2872 // checks.
2670 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2873 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2671 2874
2672 __ push(r1); // receiver 2875 __ push(r1); // receiver
2673 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback info 2876 __ mov(ip, Operand(callback)); // callback info
2674 __ Push(ip, r2, r0); 2877 __ Push(ip, r2, r0);
2675 2878
2676 // Do tail-call to the runtime system. 2879 // Do tail-call to the runtime system.
2677 ExternalReference store_callback_property = 2880 ExternalReference store_callback_property =
2678 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), 2881 ExternalReference(IC_Utility(IC::kStoreCallbackProperty),
2679 masm()->isolate()); 2882 masm()->isolate());
2680 __ TailCallExternalReference(store_callback_property, 4, 1); 2883 __ TailCallExternalReference(store_callback_property, 4, 1);
2681 2884
2682 // Handle store cache miss. 2885 // Handle store cache miss.
2683 __ bind(&miss); 2886 __ bind(&miss);
2684 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2887 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2685 __ Jump(ic, RelocInfo::CODE_TARGET); 2888 __ Jump(ic, RelocInfo::CODE_TARGET);
2686 2889
2687 // Return the generated code. 2890 // Return the generated code.
2688 return GetCode(CALLBACKS, name); 2891 return GetCode(CALLBACKS, name);
2689 } 2892 }
2690 2893
2691 2894
2692 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2895 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2693 String* name) { 2896 Handle<JSObject> receiver,
2897 Handle<String> name) {
2694 // ----------- S t a t e ------------- 2898 // ----------- S t a t e -------------
2695 // -- r0 : value 2899 // -- r0 : value
2696 // -- r1 : receiver 2900 // -- r1 : receiver
2697 // -- r2 : name 2901 // -- r2 : name
2698 // -- lr : return address 2902 // -- lr : return address
2699 // ----------------------------------- 2903 // -----------------------------------
2700 Label miss; 2904 Label miss;
2701 2905
2702 // Check that the object isn't a smi. 2906 // Check that the object isn't a smi.
2703 __ JumpIfSmi(r1, &miss); 2907 __ JumpIfSmi(r1, &miss);
(...skipping 26 matching lines...) Expand all
2730 // Handle store cache miss. 2934 // Handle store cache miss.
2731 __ bind(&miss); 2935 __ bind(&miss);
2732 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2936 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2733 __ Jump(ic, RelocInfo::CODE_TARGET); 2937 __ Jump(ic, RelocInfo::CODE_TARGET);
2734 2938
2735 // Return the generated code. 2939 // Return the generated code.
2736 return GetCode(INTERCEPTOR, name); 2940 return GetCode(INTERCEPTOR, name);
2737 } 2941 }
2738 2942
2739 2943
2740 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2944 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2741 JSGlobalPropertyCell* cell, 2945 Handle<GlobalObject> object,
2742 String* name) { 2946 Handle<JSGlobalPropertyCell> cell,
2947 Handle<String> name) {
2743 // ----------- S t a t e ------------- 2948 // ----------- S t a t e -------------
2744 // -- r0 : value 2949 // -- r0 : value
2745 // -- r1 : receiver 2950 // -- r1 : receiver
2746 // -- r2 : name 2951 // -- r2 : name
2747 // -- lr : return address 2952 // -- lr : return address
2748 // ----------------------------------- 2953 // -----------------------------------
2749 Label miss; 2954 Label miss;
2750 2955
2751 // Check that the map of the global has not changed. 2956 // Check that the map of the global has not changed.
2752 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); 2957 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
2753 __ cmp(r3, Operand(Handle<Map>(object->map()))); 2958 __ cmp(r3, Operand(Handle<Map>(object->map())));
2754 __ b(ne, &miss); 2959 __ b(ne, &miss);
2755 2960
2756 // Check that the value in the cell is not the hole. If it is, this 2961 // Check that the value in the cell is not the hole. If it is, this
2757 // cell could have been deleted and reintroducing the global needs 2962 // cell could have been deleted and reintroducing the global needs
2758 // to update the property details in the property dictionary of the 2963 // to update the property details in the property dictionary of the
2759 // global object. We bail out to the runtime system to do that. 2964 // global object. We bail out to the runtime system to do that.
2760 __ mov(r4, Operand(Handle<JSGlobalPropertyCell>(cell))); 2965 __ mov(r4, Operand(cell));
2761 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); 2966 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
2762 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); 2967 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
2763 __ cmp(r5, r6); 2968 __ cmp(r5, r6);
2764 __ b(eq, &miss); 2969 __ b(eq, &miss);
2765 2970
2766 // Store the value in the cell. 2971 // Store the value in the cell.
2767 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); 2972 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
2768 2973
2769 __ mov(r1, r0); 2974 __ mov(r1, r0);
2770 __ RecordWriteField(r4, 2975 __ RecordWriteField(r4,
(...skipping 12 matching lines...) Expand all
2783 __ bind(&miss); 2988 __ bind(&miss);
2784 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); 2989 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3);
2785 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2990 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2786 __ Jump(ic, RelocInfo::CODE_TARGET); 2991 __ Jump(ic, RelocInfo::CODE_TARGET);
2787 2992
2788 // Return the generated code. 2993 // Return the generated code.
2789 return GetCode(NORMAL, name); 2994 return GetCode(NORMAL, name);
2790 } 2995 }
2791 2996
2792 2997
2793 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2998 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
2794 JSObject* object, 2999 Handle<JSObject> object,
2795 JSObject* last) { 3000 Handle<JSObject> last) {
2796 // ----------- S t a t e ------------- 3001 // ----------- S t a t e -------------
2797 // -- r0 : receiver 3002 // -- r0 : receiver
2798 // -- lr : return address 3003 // -- lr : return address
2799 // ----------------------------------- 3004 // -----------------------------------
2800 Label miss; 3005 Label miss;
2801 3006
2802 // Check that receiver is not a smi. 3007 // Check that receiver is not a smi.
2803 __ JumpIfSmi(r0, &miss); 3008 __ JumpIfSmi(r0, &miss);
2804 3009
2805 // Check the maps of the full prototype chain. 3010 // Check the maps of the full prototype chain.
2806 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); 3011 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss);
2807 3012
2808 // If the last object in the prototype chain is a global object, 3013 // If the last object in the prototype chain is a global object,
2809 // check that the global property cell is empty. 3014 // check that the global property cell is empty.
2810 if (last->IsGlobalObject()) { 3015 if (last->IsGlobalObject()) {
2811 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 3016 GenerateCheckPropertyCell(
2812 GlobalObject::cast(last), 3017 masm(), Handle<GlobalObject>::cast(last), name, r1, &miss);
2813 name,
2814 r1,
2815 &miss);
2816 if (cell->IsFailure()) {
2817 miss.Unuse();
2818 return cell;
2819 }
2820 } 3018 }
2821 3019
2822 // Return undefined if maps of the full prototype chain are still the 3020 // Return undefined if maps of the full prototype chain are still the
2823 // same and no global property with this name contains a value. 3021 // same and no global property with this name contains a value.
2824 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 3022 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2825 __ Ret(); 3023 __ Ret();
2826 3024
2827 __ bind(&miss); 3025 __ bind(&miss);
2828 GenerateLoadMiss(masm(), Code::LOAD_IC); 3026 GenerateLoadMiss(masm(), Code::LOAD_IC);
2829 3027
2830 // Return the generated code. 3028 // Return the generated code.
2831 return GetCode(NONEXISTENT, heap()->empty_string()); 3029 return GetCode(NONEXISTENT, factory()->empty_string());
2832 } 3030 }
2833 3031
2834 3032
2835 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 3033 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
2836 JSObject* holder, 3034 Handle<JSObject> holder,
2837 int index, 3035 int index,
2838 String* name) { 3036 Handle<String> name) {
2839 // ----------- S t a t e ------------- 3037 // ----------- S t a t e -------------
2840 // -- r0 : receiver 3038 // -- r0 : receiver
2841 // -- r2 : name 3039 // -- r2 : name
2842 // -- lr : return address 3040 // -- lr : return address
2843 // ----------------------------------- 3041 // -----------------------------------
2844 Label miss; 3042 Label miss;
2845 3043
2846 GenerateLoadField(object, holder, r0, r3, r1, r4, index, name, &miss); 3044 GenerateLoadField(object, holder, r0, r3, r1, r4, index, name, &miss);
2847 __ bind(&miss); 3045 __ bind(&miss);
2848 GenerateLoadMiss(masm(), Code::LOAD_IC); 3046 GenerateLoadMiss(masm(), Code::LOAD_IC);
(...skipping 18 matching lines...) Expand all
2867 callback, name, &miss); 3065 callback, name, &miss);
2868 if (result->IsFailure()) { 3066 if (result->IsFailure()) {
2869 miss.Unuse(); 3067 miss.Unuse();
2870 return result; 3068 return result;
2871 } 3069 }
2872 3070
2873 __ bind(&miss); 3071 __ bind(&miss);
2874 GenerateLoadMiss(masm(), Code::LOAD_IC); 3072 GenerateLoadMiss(masm(), Code::LOAD_IC);
2875 3073
2876 // Return the generated code. 3074 // Return the generated code.
2877 return GetCode(CALLBACKS, name); 3075 return TryGetCode(CALLBACKS, name);
2878 } 3076 }
2879 3077
2880 3078
2881 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, 3079 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
2882 JSObject* holder, 3080 Handle<JSObject> holder,
2883 Object* value, 3081 Handle<Object> value,
2884 String* name) { 3082 Handle<String> name) {
2885 // ----------- S t a t e ------------- 3083 // ----------- S t a t e -------------
2886 // -- r0 : receiver 3084 // -- r0 : receiver
2887 // -- r2 : name 3085 // -- r2 : name
2888 // -- lr : return address 3086 // -- lr : return address
2889 // ----------------------------------- 3087 // -----------------------------------
2890 Label miss; 3088 Label miss;
2891 3089
2892 GenerateLoadConstant(object, holder, r0, r3, r1, r4, value, name, &miss); 3090 GenerateLoadConstant(object, holder, r0, r3, r1, r4, value, name, &miss);
2893 __ bind(&miss); 3091 __ bind(&miss);
2894 GenerateLoadMiss(masm(), Code::LOAD_IC); 3092 GenerateLoadMiss(masm(), Code::LOAD_IC);
2895 3093
2896 // Return the generated code. 3094 // Return the generated code.
2897 return GetCode(CONSTANT_FUNCTION, name); 3095 return GetCode(CONSTANT_FUNCTION, name);
2898 } 3096 }
2899 3097
2900 3098
2901 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, 3099 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
2902 JSObject* holder, 3100 JSObject* holder,
2903 String* name) { 3101 String* name) {
2904 // ----------- S t a t e ------------- 3102 // ----------- S t a t e -------------
2905 // -- r0 : receiver 3103 // -- r0 : receiver
2906 // -- r2 : name 3104 // -- r2 : name
2907 // -- lr : return address 3105 // -- lr : return address
2908 // ----------------------------------- 3106 // -----------------------------------
2909 Label miss; 3107 Label miss;
2910 3108
2911 LookupResult lookup; 3109 LookupResult lookup(isolate());
2912 LookupPostInterceptor(holder, name, &lookup); 3110 LookupPostInterceptor(holder, name, &lookup);
2913 GenerateLoadInterceptor(object, 3111 GenerateLoadInterceptor(object,
2914 holder, 3112 holder,
2915 &lookup, 3113 &lookup,
2916 r0, 3114 r0,
2917 r2, 3115 r2,
2918 r3, 3116 r3,
2919 r1, 3117 r1,
2920 r4, 3118 r4,
2921 name, 3119 name,
2922 &miss); 3120 &miss);
2923 __ bind(&miss); 3121 __ bind(&miss);
2924 GenerateLoadMiss(masm(), Code::LOAD_IC); 3122 GenerateLoadMiss(masm(), Code::LOAD_IC);
2925 3123
2926 // Return the generated code. 3124 // Return the generated code.
2927 return GetCode(INTERCEPTOR, name); 3125 return TryGetCode(INTERCEPTOR, name);
2928 } 3126 }
2929 3127
2930 3128
2931 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, 3129 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
2932 GlobalObject* holder, 3130 Handle<JSObject> object,
2933 JSGlobalPropertyCell* cell, 3131 Handle<GlobalObject> holder,
2934 String* name, 3132 Handle<JSGlobalPropertyCell> cell,
2935 bool is_dont_delete) { 3133 Handle<String> name,
3134 bool is_dont_delete) {
2936 // ----------- S t a t e ------------- 3135 // ----------- S t a t e -------------
2937 // -- r0 : receiver 3136 // -- r0 : receiver
2938 // -- r2 : name 3137 // -- r2 : name
2939 // -- lr : return address 3138 // -- lr : return address
2940 // ----------------------------------- 3139 // -----------------------------------
2941 Label miss; 3140 Label miss;
2942 3141
2943 // If the object is the holder then we know that it's a global 3142 // If the object is the holder then we know that it's a global
2944 // object which can only happen for contextual calls. In this case, 3143 // object which can only happen for contextual calls. In this case,
2945 // the receiver cannot be a smi. 3144 // the receiver cannot be a smi.
2946 if (object != holder) { 3145 if (!object.is_identical_to(holder)) {
2947 __ JumpIfSmi(r0, &miss); 3146 __ JumpIfSmi(r0, &miss);
2948 } 3147 }
2949 3148
2950 // Check that the map of the global has not changed. 3149 // Check that the map of the global has not changed.
2951 CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss); 3150 CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss);
2952 3151
2953 // Get the value from the cell. 3152 // Get the value from the cell.
2954 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); 3153 __ mov(r3, Operand(cell));
2955 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); 3154 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
2956 3155
2957 // Check for deleted property if property can actually be deleted. 3156 // Check for deleted property if property can actually be deleted.
2958 if (!is_dont_delete) { 3157 if (!is_dont_delete) {
2959 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 3158 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
2960 __ cmp(r4, ip); 3159 __ cmp(r4, ip);
2961 __ b(eq, &miss); 3160 __ b(eq, &miss);
2962 } 3161 }
2963 3162
2964 __ mov(r0, r4); 3163 __ mov(r0, r4);
2965 Counters* counters = masm()->isolate()->counters(); 3164 Counters* counters = masm()->isolate()->counters();
2966 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 3165 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
2967 __ Ret(); 3166 __ Ret();
2968 3167
2969 __ bind(&miss); 3168 __ bind(&miss);
2970 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3); 3169 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3);
2971 GenerateLoadMiss(masm(), Code::LOAD_IC); 3170 GenerateLoadMiss(masm(), Code::LOAD_IC);
2972 3171
2973 // Return the generated code. 3172 // Return the generated code.
2974 return GetCode(NORMAL, name); 3173 return GetCode(NORMAL, name);
2975 } 3174 }
2976 3175
2977 3176
2978 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 3177 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
2979 JSObject* receiver, 3178 Handle<JSObject> receiver,
2980 JSObject* holder, 3179 Handle<JSObject> holder,
2981 int index) { 3180 int index) {
2982 // ----------- S t a t e ------------- 3181 // ----------- S t a t e -------------
2983 // -- lr : return address 3182 // -- lr : return address
2984 // -- r0 : key 3183 // -- r0 : key
2985 // -- r1 : receiver 3184 // -- r1 : receiver
2986 // ----------------------------------- 3185 // -----------------------------------
2987 Label miss; 3186 Label miss;
2988 3187
2989 // Check the key is the cached one. 3188 // Check the key is the cached one.
2990 __ cmp(r0, Operand(Handle<String>(name))); 3189 __ cmp(r0, Operand(name));
2991 __ b(ne, &miss); 3190 __ b(ne, &miss);
2992 3191
2993 GenerateLoadField(receiver, holder, r1, r2, r3, r4, index, name, &miss); 3192 GenerateLoadField(receiver, holder, r1, r2, r3, r4, index, name, &miss);
2994 __ bind(&miss); 3193 __ bind(&miss);
2995 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3194 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2996 3195
2997 return GetCode(FIELD, name); 3196 return GetCode(FIELD, name);
2998 } 3197 }
2999 3198
3000 3199
(...skipping 16 matching lines...) Expand all
3017 MaybeObject* result = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, 3216 MaybeObject* result = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3,
3018 r4, callback, name, &miss); 3217 r4, callback, name, &miss);
3019 if (result->IsFailure()) { 3218 if (result->IsFailure()) {
3020 miss.Unuse(); 3219 miss.Unuse();
3021 return result; 3220 return result;
3022 } 3221 }
3023 3222
3024 __ bind(&miss); 3223 __ bind(&miss);
3025 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3224 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3026 3225
3027 return GetCode(CALLBACKS, name); 3226 return TryGetCode(CALLBACKS, name);
3028 } 3227 }
3029 3228
3030 3229
3031 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, 3230 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
3032 JSObject* receiver, 3231 Handle<String> name,
3033 JSObject* holder, 3232 Handle<JSObject> receiver,
3034 Object* value) { 3233 Handle<JSObject> holder,
3234 Handle<Object> value) {
3035 // ----------- S t a t e ------------- 3235 // ----------- S t a t e -------------
3036 // -- lr : return address 3236 // -- lr : return address
3037 // -- r0 : key 3237 // -- r0 : key
3038 // -- r1 : receiver 3238 // -- r1 : receiver
3039 // ----------------------------------- 3239 // -----------------------------------
3040 Label miss; 3240 Label miss;
3041 3241
3042 // Check the key is the cached one. 3242 // Check the key is the cached one.
3043 __ cmp(r0, Operand(Handle<String>(name))); 3243 __ cmp(r0, Operand(name));
3044 __ b(ne, &miss); 3244 __ b(ne, &miss);
3045 3245
3046 GenerateLoadConstant(receiver, holder, r1, r2, r3, r4, value, name, &miss); 3246 GenerateLoadConstant(receiver, holder, r1, r2, r3, r4, value, name, &miss);
3047 __ bind(&miss); 3247 __ bind(&miss);
3048 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3248 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3049 3249
3050 // Return the generated code. 3250 // Return the generated code.
3051 return GetCode(CONSTANT_FUNCTION, name); 3251 return GetCode(CONSTANT_FUNCTION, name);
3052 } 3252 }
3053 3253
3054 3254
3055 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3255 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3056 JSObject* holder, 3256 JSObject* holder,
3057 String* name) { 3257 String* name) {
3058 // ----------- S t a t e ------------- 3258 // ----------- S t a t e -------------
3059 // -- lr : return address 3259 // -- lr : return address
3060 // -- r0 : key 3260 // -- r0 : key
3061 // -- r1 : receiver 3261 // -- r1 : receiver
3062 // ----------------------------------- 3262 // -----------------------------------
3063 Label miss; 3263 Label miss;
3064 3264
3065 // Check the key is the cached one. 3265 // Check the key is the cached one.
3066 __ cmp(r0, Operand(Handle<String>(name))); 3266 __ cmp(r0, Operand(Handle<String>(name)));
3067 __ b(ne, &miss); 3267 __ b(ne, &miss);
3068 3268
3069 LookupResult lookup; 3269 LookupResult lookup(isolate());
3070 LookupPostInterceptor(holder, name, &lookup); 3270 LookupPostInterceptor(holder, name, &lookup);
3071 GenerateLoadInterceptor(receiver, 3271 GenerateLoadInterceptor(receiver,
3072 holder, 3272 holder,
3073 &lookup, 3273 &lookup,
3074 r1, 3274 r1,
3075 r0, 3275 r0,
3076 r2, 3276 r2,
3077 r3, 3277 r3,
3078 r4, 3278 r4,
3079 name, 3279 name,
3080 &miss); 3280 &miss);
3081 __ bind(&miss); 3281 __ bind(&miss);
3082 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3282 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3083 3283
3084 return GetCode(INTERCEPTOR, name); 3284 return TryGetCode(INTERCEPTOR, name);
3085 } 3285 }
3086 3286
3087 3287
3088 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3288 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
3289 Handle<String> name) {
3089 // ----------- S t a t e ------------- 3290 // ----------- S t a t e -------------
3090 // -- lr : return address 3291 // -- lr : return address
3091 // -- r0 : key 3292 // -- r0 : key
3092 // -- r1 : receiver 3293 // -- r1 : receiver
3093 // ----------------------------------- 3294 // -----------------------------------
3094 Label miss; 3295 Label miss;
3095 3296
3096 // Check the key is the cached one. 3297 // Check the key is the cached one.
3097 __ cmp(r0, Operand(Handle<String>(name))); 3298 __ cmp(r0, Operand(name));
3098 __ b(ne, &miss); 3299 __ b(ne, &miss);
3099 3300
3100 GenerateLoadArrayLength(masm(), r1, r2, &miss); 3301 GenerateLoadArrayLength(masm(), r1, r2, &miss);
3101 __ bind(&miss); 3302 __ bind(&miss);
3102 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3303 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3103 3304
3104 return GetCode(CALLBACKS, name); 3305 return GetCode(CALLBACKS, name);
3105 } 3306 }
3106 3307
3107 3308
3108 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
3310 Handle<String> name) {
3109 // ----------- S t a t e ------------- 3311 // ----------- S t a t e -------------
3110 // -- lr : return address 3312 // -- lr : return address
3111 // -- r0 : key 3313 // -- r0 : key
3112 // -- r1 : receiver 3314 // -- r1 : receiver
3113 // ----------------------------------- 3315 // -----------------------------------
3114 Label miss; 3316 Label miss;
3115 3317
3116 Counters* counters = masm()->isolate()->counters(); 3318 Counters* counters = masm()->isolate()->counters();
3117 __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3); 3319 __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3);
3118 3320
3119 // Check the key is the cached one. 3321 // Check the key is the cached one.
3120 __ cmp(r0, Operand(Handle<String>(name))); 3322 __ cmp(r0, Operand(name));
3121 __ b(ne, &miss); 3323 __ b(ne, &miss);
3122 3324
3123 GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true); 3325 GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true);
3124 __ bind(&miss); 3326 __ bind(&miss);
3125 __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3); 3327 __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3);
3126 3328
3127 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3329 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3128 3330
3129 return GetCode(CALLBACKS, name); 3331 return GetCode(CALLBACKS, name);
3130 } 3332 }
3131 3333
3132 3334
3133 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3335 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
3336 Handle<String> name) {
3134 // ----------- S t a t e ------------- 3337 // ----------- S t a t e -------------
3135 // -- lr : return address 3338 // -- lr : return address
3136 // -- r0 : key 3339 // -- r0 : key
3137 // -- r1 : receiver 3340 // -- r1 : receiver
3138 // ----------------------------------- 3341 // -----------------------------------
3139 Label miss; 3342 Label miss;
3140 3343
3141 Counters* counters = masm()->isolate()->counters(); 3344 Counters* counters = masm()->isolate()->counters();
3142 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); 3345 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
3143 3346
3144 // Check the name hasn't changed. 3347 // Check the name hasn't changed.
3145 __ cmp(r0, Operand(Handle<String>(name))); 3348 __ cmp(r0, Operand(name));
3146 __ b(ne, &miss); 3349 __ b(ne, &miss);
3147 3350
3148 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss); 3351 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss);
3149 __ bind(&miss); 3352 __ bind(&miss);
3150 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); 3353 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
3151 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3354 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3152 3355
3153 return GetCode(CALLBACKS, name); 3356 return GetCode(CALLBACKS, name);
3154 } 3357 }
3155 3358
3156 3359
3157 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { 3360 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
3361 Handle<Map> receiver_map) {
3158 // ----------- S t a t e ------------- 3362 // ----------- S t a t e -------------
3159 // -- lr : return address 3363 // -- lr : return address
3160 // -- r0 : key 3364 // -- r0 : key
3161 // -- r1 : receiver 3365 // -- r1 : receiver
3162 // ----------------------------------- 3366 // -----------------------------------
3163 Code* stub;
3164 ElementsKind elements_kind = receiver_map->elements_kind(); 3367 ElementsKind elements_kind = receiver_map->elements_kind();
3165 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); 3368 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode();
3166 if (!maybe_stub->To(&stub)) return maybe_stub; 3369
3167 __ DispatchMap(r1, 3370 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK);
3168 r2,
3169 Handle<Map>(receiver_map),
3170 Handle<Code>(stub),
3171 DO_SMI_CHECK);
3172 3371
3173 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3372 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3174 __ Jump(ic, RelocInfo::CODE_TARGET); 3373 __ Jump(ic, RelocInfo::CODE_TARGET);
3175 3374
3176 // Return the generated code. 3375 // Return the generated code.
3177 return GetCode(NORMAL, NULL); 3376 return GetCode(NORMAL, factory()->empty_string());
3178 } 3377 }
3179 3378
3180 3379
3181 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( 3380 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
3182 MapList* receiver_maps, 3381 MapHandleList* receiver_maps,
3183 CodeList* handler_ics) { 3382 CodeHandleList* handler_ics) {
3184 // ----------- S t a t e ------------- 3383 // ----------- S t a t e -------------
3185 // -- lr : return address 3384 // -- lr : return address
3186 // -- r0 : key 3385 // -- r0 : key
3187 // -- r1 : receiver 3386 // -- r1 : receiver
3188 // ----------------------------------- 3387 // -----------------------------------
3189 Label miss; 3388 Label miss;
3190 __ JumpIfSmi(r1, &miss); 3389 __ JumpIfSmi(r1, &miss);
3191 3390
3192 int receiver_count = receiver_maps->length(); 3391 int receiver_count = receiver_maps->length();
3193 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 3392 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
3194 for (int current = 0; current < receiver_count; ++current) { 3393 for (int current = 0; current < receiver_count; ++current) {
3195 Handle<Map> map(receiver_maps->at(current)); 3394 __ mov(ip, Operand(receiver_maps->at(current)));
3196 Handle<Code> code(handler_ics->at(current));
3197 __ mov(ip, Operand(map));
3198 __ cmp(r2, ip); 3395 __ cmp(r2, ip);
3199 __ Jump(code, RelocInfo::CODE_TARGET, eq); 3396 __ Jump(handler_ics->at(current), RelocInfo::CODE_TARGET, eq);
3200 } 3397 }
3201 3398
3202 __ bind(&miss); 3399 __ bind(&miss);
3203 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3400 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss();
3204 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); 3401 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
3205 3402
3206 // Return the generated code. 3403 // Return the generated code.
3207 return GetCode(NORMAL, NULL, MEGAMORPHIC); 3404 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
3208 } 3405 }
3209 3406
3210 3407
3211 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 3408 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
3212 int index, 3409 int index,
3213 Map* transition, 3410 Handle<Map> transition,
3214 String* name) { 3411 Handle<String> name) {
3215 // ----------- S t a t e ------------- 3412 // ----------- S t a t e -------------
3216 // -- r0 : value 3413 // -- r0 : value
3217 // -- r1 : name 3414 // -- r1 : name
3218 // -- r2 : receiver 3415 // -- r2 : receiver
3219 // -- lr : return address 3416 // -- lr : return address
3220 // ----------------------------------- 3417 // -----------------------------------
3221 Label miss; 3418 Label miss;
3222 3419
3223 Counters* counters = masm()->isolate()->counters(); 3420 Counters* counters = masm()->isolate()->counters();
3224 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); 3421 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4);
3225 3422
3226 // Check that the name has not changed. 3423 // Check that the name has not changed.
3227 __ cmp(r1, Operand(Handle<String>(name))); 3424 __ cmp(r1, Operand(name));
3228 __ b(ne, &miss); 3425 __ b(ne, &miss);
3229 3426
3230 // r3 is used as scratch register. r1 and r2 keep their values if a jump to 3427 // r3 is used as scratch register. r1 and r2 keep their values if a jump to
3231 // the miss label is generated. 3428 // the miss label is generated.
3232 GenerateStoreField(masm(), 3429 GenerateStoreField(masm(), object, index, transition, r2, r1, r3, &miss);
3233 object,
3234 index,
3235 transition,
3236 r2, r1, r3,
3237 &miss);
3238 __ bind(&miss); 3430 __ bind(&miss);
3239 3431
3240 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4); 3432 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4);
3241 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); 3433 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
3242 __ Jump(ic, RelocInfo::CODE_TARGET); 3434 __ Jump(ic, RelocInfo::CODE_TARGET);
3243 3435
3244 // Return the generated code. 3436 // Return the generated code.
3245 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 3437 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
3246 } 3438 }
3247 3439
3248 3440
3249 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { 3441 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
3442 Handle<Map> receiver_map) {
3250 // ----------- S t a t e ------------- 3443 // ----------- S t a t e -------------
3251 // -- r0 : value 3444 // -- r0 : value
3252 // -- r1 : key 3445 // -- r1 : key
3253 // -- r2 : receiver 3446 // -- r2 : receiver
3254 // -- lr : return address 3447 // -- lr : return address
3255 // -- r3 : scratch 3448 // -- r3 : scratch
3256 // ----------------------------------- 3449 // -----------------------------------
3257 Code* stub;
3258 ElementsKind elements_kind = receiver_map->elements_kind(); 3450 ElementsKind elements_kind = receiver_map->elements_kind();
3259 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 3451 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
3260 MaybeObject* maybe_stub = 3452 Handle<Code> stub =
3261 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); 3453 KeyedStoreElementStub(is_js_array, elements_kind).GetCode();
3262 if (!maybe_stub->To(&stub)) return maybe_stub; 3454
3263 __ DispatchMap(r2, 3455 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK);
3264 r3,
3265 Handle<Map>(receiver_map),
3266 Handle<Code>(stub),
3267 DO_SMI_CHECK);
3268 3456
3269 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3457 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3270 __ Jump(ic, RelocInfo::CODE_TARGET); 3458 __ Jump(ic, RelocInfo::CODE_TARGET);
3271 3459
3272 // Return the generated code. 3460 // Return the generated code.
3273 return GetCode(NORMAL, NULL); 3461 return GetCode(NORMAL, factory()->empty_string());
3274 } 3462 }
3275 3463
3276 3464
3277 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( 3465 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
3278 MapList* receiver_maps, 3466 MapHandleList* receiver_maps,
3279 CodeList* handler_stubs, 3467 CodeHandleList* handler_stubs,
3280 MapList* transitioned_maps) { 3468 MapHandleList* transitioned_maps) {
3281 // ----------- S t a t e ------------- 3469 // ----------- S t a t e -------------
3282 // -- r0 : value 3470 // -- r0 : value
3283 // -- r1 : key 3471 // -- r1 : key
3284 // -- r2 : receiver 3472 // -- r2 : receiver
3285 // -- lr : return address 3473 // -- lr : return address
3286 // -- r3 : scratch 3474 // -- r3 : scratch
3287 // ----------------------------------- 3475 // -----------------------------------
3288 Label miss; 3476 Label miss;
3289 __ JumpIfSmi(r2, &miss); 3477 __ JumpIfSmi(r2, &miss);
3290 3478
3291 int receiver_count = receiver_maps->length(); 3479 int receiver_count = receiver_maps->length();
3292 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); 3480 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
3293 for (int i = 0; i < receiver_count; ++i) { 3481 for (int i = 0; i < receiver_count; ++i) {
3294 Handle<Map> map(receiver_maps->at(i)); 3482 __ mov(ip, Operand(receiver_maps->at(i)));
3295 Handle<Code> code(handler_stubs->at(i));
3296 __ mov(ip, Operand(map));
3297 __ cmp(r3, ip); 3483 __ cmp(r3, ip);
3298 if (transitioned_maps->at(i) == NULL) { 3484 if (transitioned_maps->at(i).is_null()) {
3299 __ Jump(code, RelocInfo::CODE_TARGET, eq); 3485 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
3300 } else { 3486 } else {
3301 Label next_map; 3487 Label next_map;
3302 __ b(eq, &next_map); 3488 __ b(ne, &next_map);
3303 __ mov(r4, Operand(Handle<Map>(transitioned_maps->at(i)))); 3489 __ mov(r3, Operand(transitioned_maps->at(i)));
3304 __ Jump(code, RelocInfo::CODE_TARGET, al); 3490 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
3305 __ bind(&next_map); 3491 __ bind(&next_map);
3306 } 3492 }
3307 } 3493 }
3308 3494
3309 __ bind(&miss); 3495 __ bind(&miss);
3310 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3496 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
3311 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); 3497 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
3312 3498
3313 // Return the generated code. 3499 // Return the generated code.
3314 return GetCode(NORMAL, NULL, MEGAMORPHIC); 3500 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
3315 } 3501 }
3316 3502
3317 3503
3318 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3504 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3319 // ----------- S t a t e ------------- 3505 // ----------- S t a t e -------------
3320 // -- r0 : argc 3506 // -- r0 : argc
3321 // -- r1 : constructor 3507 // -- r1 : constructor
3322 // -- lr : return address 3508 // -- lr : return address
3323 // -- [sp] : last argument 3509 // -- [sp] : last argument
3324 // ----------------------------------- 3510 // -----------------------------------
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after
4460 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4646 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4461 __ Jump(ic_miss, RelocInfo::CODE_TARGET); 4647 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
4462 } 4648 }
4463 4649
4464 4650
4465 #undef __ 4651 #undef __
4466 4652
4467 } } // namespace v8::internal 4653 } } // namespace v8::internal
4468 4654
4469 #endif // V8_TARGET_ARCH_ARM 4655 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.cc ('k') | src/array.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698