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

Side by Side Diff: src/ic/arm/ic-arm.cc

Issue 1189153002: Revert of [strong] Implement strong mode restrictions on property access (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/arm/handler-compiler-arm.cc ('k') | src/ic/arm64/handler-compiler-arm64.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 __ ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 154 __ ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
155 __ cmp(scratch, Operand(JS_OBJECT_TYPE)); 155 __ cmp(scratch, Operand(JS_OBJECT_TYPE));
156 __ b(lt, slow); 156 __ b(lt, slow);
157 } 157 }
158 158
159 159
160 // Loads an indexed element from a fast case array. 160 // Loads an indexed element from a fast case array.
161 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 161 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
162 Register key, Register elements, 162 Register key, Register elements,
163 Register scratch1, Register scratch2, 163 Register scratch1, Register scratch2,
164 Register result, Label* slow, 164 Register result, Label* slow) {
165 LanguageMode language_mode) {
166 // Register use: 165 // Register use:
167 // 166 //
168 // receiver - holds the receiver on entry. 167 // receiver - holds the receiver on entry.
169 // Unchanged unless 'result' is the same register. 168 // Unchanged unless 'result' is the same register.
170 // 169 //
171 // key - holds the smi key on entry. 170 // key - holds the smi key on entry.
172 // Unchanged unless 'result' is the same register. 171 // Unchanged unless 'result' is the same register.
173 // 172 //
174 // result - holds the result on exit if the load succeeded. 173 // result - holds the result on exit if the load succeeded.
175 // Allowed to be the the same as 'receiver' or 'key'. 174 // Allowed to be the the same as 'receiver' or 'key'.
176 // Unchanged on bailout so 'receiver' and 'key' can be safely 175 // Unchanged on bailout so 'receiver' and 'key' can be safely
177 // used by further computation. 176 // used by further computation.
178 // 177 //
179 // Scratch registers: 178 // Scratch registers:
180 // 179 //
181 // elements - holds the elements of the receiver and its prototypes. 180 // elements - holds the elements of the receiver and its prototypes.
182 // 181 //
183 // scratch1 - used to hold elements length, bit fields, base addresses. 182 // scratch1 - used to hold elements length, bit fields, base addresses.
184 // 183 //
185 // scratch2 - used to hold maps, prototypes, and the loaded value. 184 // scratch2 - used to hold maps, prototypes, and the loaded value.
186 Label check_prototypes, check_next_prototype; 185 Label check_prototypes, check_next_prototype;
187 Label done, in_bounds, absent; 186 Label done, in_bounds, return_undefined;
188 187
189 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 188 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
190 __ AssertFastElements(elements); 189 __ AssertFastElements(elements);
191 190
192 // Check that the key (index) is within bounds. 191 // Check that the key (index) is within bounds.
193 __ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); 192 __ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
194 __ cmp(key, Operand(scratch1)); 193 __ cmp(key, Operand(scratch1));
195 __ b(lo, &in_bounds); 194 __ b(lo, &in_bounds);
196 // Out-of-bounds. Check the prototype chain to see if we can just return 195 // Out-of-bounds. Check the prototype chain to see if we can just return
197 // 'undefined'. 196 // 'undefined'.
198 __ cmp(key, Operand(0)); 197 __ cmp(key, Operand(0));
199 __ b(lt, slow); // Negative keys can't take the fast OOB path. 198 __ b(lt, slow); // Negative keys can't take the fast OOB path.
200 __ bind(&check_prototypes); 199 __ bind(&check_prototypes);
201 __ ldr(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 200 __ ldr(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
202 __ bind(&check_next_prototype); 201 __ bind(&check_next_prototype);
203 __ ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset)); 202 __ ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
204 // scratch2: current prototype 203 // scratch2: current prototype
205 __ CompareRoot(scratch2, Heap::kNullValueRootIndex); 204 __ CompareRoot(scratch2, Heap::kNullValueRootIndex);
206 __ b(eq, &absent); 205 __ b(eq, &return_undefined);
207 __ ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset)); 206 __ ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
208 __ ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset)); 207 __ ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
209 // elements: elements of current prototype 208 // elements: elements of current prototype
210 // scratch2: map of current prototype 209 // scratch2: map of current prototype
211 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE); 210 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE);
212 __ b(lo, slow); 211 __ b(lo, slow);
213 __ ldrb(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset)); 212 __ ldrb(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
214 __ tst(scratch1, Operand((1 << Map::kIsAccessCheckNeeded) | 213 __ tst(scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
215 (1 << Map::kHasIndexedInterceptor))); 214 (1 << Map::kHasIndexedInterceptor)));
216 __ b(ne, slow); 215 __ b(ne, slow);
217 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex); 216 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
218 __ b(ne, slow); 217 __ b(ne, slow);
219 __ jmp(&check_next_prototype); 218 __ jmp(&check_next_prototype);
220 219
221 __ bind(&absent); 220 __ bind(&return_undefined);
222 if (is_strong(language_mode)) { 221 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
223 // Strong mode accesses must throw in this case, so call the runtime. 222 __ jmp(&done);
224 __ jmp(slow);
225 } else {
226 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
227 __ jmp(&done);
228 }
229 223
230 __ bind(&in_bounds); 224 __ bind(&in_bounds);
231 // Fast case: Do the load. 225 // Fast case: Do the load.
232 __ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 226 __ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
233 __ ldr(scratch2, MemOperand::PointerAddressFromSmiKey(scratch1, key)); 227 __ ldr(scratch2, MemOperand::PointerAddressFromSmiKey(scratch1, key));
234 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex); 228 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
235 // In case the loaded value is the_hole we have to check the prototype chain. 229 // In case the loaded value is the_hole we have to check the prototype chain.
236 __ b(eq, &check_prototypes); 230 __ b(eq, &check_prototypes);
237 __ mov(result, scratch2); 231 __ mov(result, scratch2);
238 __ bind(&done); 232 __ bind(&done);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 Label slow; 271 Label slow;
278 272
279 __ ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), 273 __ ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
280 JSObject::kPropertiesOffset)); 274 JSObject::kPropertiesOffset));
281 GenerateDictionaryLoad(masm, &slow, dictionary, 275 GenerateDictionaryLoad(masm, &slow, dictionary,
282 LoadDescriptor::NameRegister(), r0, r3, r4); 276 LoadDescriptor::NameRegister(), r0, r3, r4);
283 __ Ret(); 277 __ Ret();
284 278
285 // Dictionary load failed, go slow (but don't miss). 279 // Dictionary load failed, go slow (but don't miss).
286 __ bind(&slow); 280 __ bind(&slow);
287 GenerateSlow(masm); 281 GenerateRuntimeGetProperty(masm);
288 } 282 }
289 283
290 284
291 // A register that isn't one of the parameters to the load ic. 285 // A register that isn't one of the parameters to the load ic.
292 static const Register LoadIC_TempRegister() { return r3; } 286 static const Register LoadIC_TempRegister() { return r3; }
293 287
294 288
295 static void LoadIC_PushArgs(MacroAssembler* masm) { 289 static void LoadIC_PushArgs(MacroAssembler* masm) {
296 Register receiver = LoadDescriptor::ReceiverRegister(); 290 Register receiver = LoadDescriptor::ReceiverRegister();
297 Register name = LoadDescriptor::NameRegister(); 291 Register name = LoadDescriptor::NameRegister();
(...skipping 14 matching lines...) Expand all
312 306
313 LoadIC_PushArgs(masm); 307 LoadIC_PushArgs(masm);
314 308
315 // Perform tail call to the entry. 309 // Perform tail call to the entry.
316 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 310 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
317 int arg_count = 4; 311 int arg_count = 4;
318 __ TailCallExternalReference(ref, arg_count, 1); 312 __ TailCallExternalReference(ref, arg_count, 1);
319 } 313 }
320 314
321 315
322 void LoadIC::GenerateSlow(MacroAssembler* masm) { 316 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
323 // The return address is in lr. 317 // The return address is in lr.
324 318
325 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); 319 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
326 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); 320 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
327 321
328 // Perform tail call to the entry. 322 __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
329 ExternalReference ref =
330 ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
331 int arg_count = 2;
332 __ TailCallExternalReference(ref, arg_count, 1);
333 } 323 }
334 324
335 325
336 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 326 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
337 // The return address is in lr. 327 // The return address is in lr.
338 Isolate* isolate = masm->isolate(); 328 Isolate* isolate = masm->isolate();
339 329
340 DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::SlotRegister(), 330 DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::SlotRegister(),
341 LoadWithVectorDescriptor::VectorRegister())); 331 LoadWithVectorDescriptor::VectorRegister()));
342 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5); 332 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5);
343 333
344 LoadIC_PushArgs(masm); 334 LoadIC_PushArgs(masm);
345 335
346 // Perform tail call to the entry. 336 // Perform tail call to the entry.
347 ExternalReference ref = 337 ExternalReference ref =
348 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 338 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
349 int arg_count = 4; 339 int arg_count = 4;
350 __ TailCallExternalReference(ref, arg_count, 1); 340 __ TailCallExternalReference(ref, arg_count, 1);
351 } 341 }
352 342
353 343
354 void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) { 344 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
355 // The return address is in lr. 345 // The return address is in lr.
356 346
357 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 347 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
358 348
359 // Perform tail call to the entry. 349 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
360 ExternalReference ref =
361 ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
362 int arg_count = 2;
363 __ TailCallExternalReference(ref, arg_count, 1);
364 } 350 }
365 351
366 352
367 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm, 353 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
368 LanguageMode language_mode) {
369 // The return address is in lr. 354 // The return address is in lr.
370 Label slow, check_name, index_smi, index_name, property_array_property; 355 Label slow, check_name, index_smi, index_name, property_array_property;
371 Label probe_dictionary, check_number_dictionary; 356 Label probe_dictionary, check_number_dictionary;
372 357
373 Register key = LoadDescriptor::NameRegister(); 358 Register key = LoadDescriptor::NameRegister();
374 Register receiver = LoadDescriptor::ReceiverRegister(); 359 Register receiver = LoadDescriptor::ReceiverRegister();
375 DCHECK(key.is(r2)); 360 DCHECK(key.is(r2));
376 DCHECK(receiver.is(r1)); 361 DCHECK(receiver.is(r1));
377 362
378 Isolate* isolate = masm->isolate(); 363 Isolate* isolate = masm->isolate();
379 364
380 // Check that the key is a smi. 365 // Check that the key is a smi.
381 __ JumpIfNotSmi(key, &check_name); 366 __ JumpIfNotSmi(key, &check_name);
382 __ bind(&index_smi); 367 __ bind(&index_smi);
383 // Now the key is known to be a smi. This place is also jumped to from below 368 // Now the key is known to be a smi. This place is also jumped to from below
384 // where a numeric string is converted to a smi. 369 // where a numeric string is converted to a smi.
385 370
386 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3, 371 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3,
387 Map::kHasIndexedInterceptor, &slow); 372 Map::kHasIndexedInterceptor, &slow);
388 373
389 // Check the receiver's map to see if it has fast elements. 374 // Check the receiver's map to see if it has fast elements.
390 __ CheckFastElements(r0, r3, &check_number_dictionary); 375 __ CheckFastElements(r0, r3, &check_number_dictionary);
391 376
392 GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow, 377 GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow);
393 language_mode);
394 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3); 378 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3);
395 __ Ret(); 379 __ Ret();
396 380
397 __ bind(&check_number_dictionary); 381 __ bind(&check_number_dictionary);
398 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); 382 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
399 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); 383 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset));
400 384
401 // Check whether the elements is a number dictionary. 385 // Check whether the elements is a number dictionary.
402 // r3: elements map 386 // r3: elements map
403 // r4: elements 387 // r4: elements
404 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 388 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
405 __ cmp(r3, ip); 389 __ cmp(r3, ip);
406 __ b(ne, &slow); 390 __ b(ne, &slow);
407 __ SmiUntag(r0, key); 391 __ SmiUntag(r0, key);
408 __ LoadFromNumberDictionary(&slow, r4, key, r0, r0, r3, r5); 392 __ LoadFromNumberDictionary(&slow, r4, key, r0, r0, r3, r5);
409 __ Ret(); 393 __ Ret();
410 394
411 // Slow case, key and receiver still in r2 and r1. 395 // Slow case, key and receiver still in r2 and r1.
412 __ bind(&slow); 396 __ bind(&slow);
413 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r4, 397 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r4,
414 r3); 398 r3);
415 GenerateSlow(masm); 399 GenerateRuntimeGetProperty(masm);
416 400
417 __ bind(&check_name); 401 __ bind(&check_name);
418 GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow); 402 GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow);
419 403
420 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3, 404 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3,
421 Map::kHasNamedInterceptor, &slow); 405 Map::kHasNamedInterceptor, &slow);
422 406
423 // If the receiver is a fast-case object, check the stub cache. Otherwise 407 // If the receiver is a fast-case object, check the stub cache. Otherwise
424 // probe the dictionary. 408 // probe the dictionary.
425 __ ldr(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 409 __ ldr(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 patcher.EmitCondition(ne); 862 patcher.EmitCondition(ne);
879 } else { 863 } else {
880 DCHECK(Assembler::GetCondition(branch_instr) == ne); 864 DCHECK(Assembler::GetCondition(branch_instr) == ne);
881 patcher.EmitCondition(eq); 865 patcher.EmitCondition(eq);
882 } 866 }
883 } 867 }
884 } // namespace internal 868 } // namespace internal
885 } // namespace v8 869 } // namespace v8
886 870
887 #endif // V8_TARGET_ARCH_ARM 871 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/ic/arm/handler-compiler-arm.cc ('k') | src/ic/arm64/handler-compiler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698