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

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

Issue 1168093002: [strong] Implement strong mode restrictions on property access (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase 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/ppc/handler-compiler-ppc.cc ('k') | src/ic/x64/handler-compiler-x64.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 7 #if V8_TARGET_ARCH_PPC
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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 160 __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
161 __ cmpi(scratch, Operand(JS_OBJECT_TYPE)); 161 __ cmpi(scratch, Operand(JS_OBJECT_TYPE));
162 __ blt(slow); 162 __ blt(slow);
163 } 163 }
164 164
165 165
166 // Loads an indexed element from a fast case array. 166 // Loads an indexed element from a fast case array.
167 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 167 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
168 Register key, Register elements, 168 Register key, Register elements,
169 Register scratch1, Register scratch2, 169 Register scratch1, Register scratch2,
170 Register result, Label* slow) { 170 Register result, Label* slow,
171 LanguageMode language_mode) {
171 // Register use: 172 // Register use:
172 // 173 //
173 // receiver - holds the receiver on entry. 174 // receiver - holds the receiver on entry.
174 // Unchanged unless 'result' is the same register. 175 // Unchanged unless 'result' is the same register.
175 // 176 //
176 // key - holds the smi key on entry. 177 // key - holds the smi key on entry.
177 // Unchanged unless 'result' is the same register. 178 // Unchanged unless 'result' is the same register.
178 // 179 //
179 // result - holds the result on exit if the load succeeded. 180 // result - holds the result on exit if the load succeeded.
180 // Allowed to be the the same as 'receiver' or 'key'. 181 // Allowed to be the the same as 'receiver' or 'key'.
181 // Unchanged on bailout so 'receiver' and 'key' can be safely 182 // Unchanged on bailout so 'receiver' and 'key' can be safely
182 // used by further computation. 183 // used by further computation.
183 // 184 //
184 // Scratch registers: 185 // Scratch registers:
185 // 186 //
186 // elements - holds the elements of the receiver and its protoypes. 187 // elements - holds the elements of the receiver and its protoypes.
187 // 188 //
188 // scratch1 - used to hold elements length, bit fields, base addresses. 189 // scratch1 - used to hold elements length, bit fields, base addresses.
189 // 190 //
190 // scratch2 - used to hold maps, prototypes, and the loaded value. 191 // scratch2 - used to hold maps, prototypes, and the loaded value.
191 Label check_prototypes, check_next_prototype; 192 Label check_prototypes, check_next_prototype;
192 Label done, in_bounds, return_undefined; 193 Label done, in_bounds, absent;
193 194
194 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 195 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
195 __ AssertFastElements(elements); 196 __ AssertFastElements(elements);
196 197
197 // Check that the key (index) is within bounds. 198 // Check that the key (index) is within bounds.
198 __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); 199 __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
199 __ cmpl(key, scratch1); 200 __ cmpl(key, scratch1);
200 __ blt(&in_bounds); 201 __ blt(&in_bounds);
201 // Out-of-bounds. Check the prototype chain to see if we can just return 202 // Out-of-bounds. Check the prototype chain to see if we can just return
202 // 'undefined'. 203 // 'undefined'.
203 __ cmpi(key, Operand::Zero()); 204 __ cmpi(key, Operand::Zero());
204 __ blt(slow); // Negative keys can't take the fast OOB path. 205 __ blt(slow); // Negative keys can't take the fast OOB path.
205 __ bind(&check_prototypes); 206 __ bind(&check_prototypes);
206 __ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 207 __ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
207 __ bind(&check_next_prototype); 208 __ bind(&check_next_prototype);
208 __ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset)); 209 __ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
209 // scratch2: current prototype 210 // scratch2: current prototype
210 __ CompareRoot(scratch2, Heap::kNullValueRootIndex); 211 __ CompareRoot(scratch2, Heap::kNullValueRootIndex);
211 __ beq(&return_undefined); 212 __ beq(&absent);
212 __ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset)); 213 __ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
213 __ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset)); 214 __ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
214 // elements: elements of current prototype 215 // elements: elements of current prototype
215 // scratch2: map of current prototype 216 // scratch2: map of current prototype
216 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE); 217 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE);
217 __ blt(slow); 218 __ blt(slow);
218 __ lbz(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset)); 219 __ lbz(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
219 __ andi(r0, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) | 220 __ andi(r0, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
220 (1 << Map::kHasIndexedInterceptor))); 221 (1 << Map::kHasIndexedInterceptor)));
221 __ bne(slow, cr0); 222 __ bne(slow, cr0);
222 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex); 223 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
223 __ bne(slow); 224 __ bne(slow);
224 __ jmp(&check_next_prototype); 225 __ jmp(&check_next_prototype);
225 226
226 __ bind(&return_undefined); 227 __ bind(&absent);
227 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 228 if (is_strong(language_mode)) {
228 __ jmp(&done); 229 // Strong mode accesses must throw in this case, so call the runtime.
230 __ jmp(slow);
231 } else {
232 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
233 __ jmp(&done);
234 }
229 235
230 __ bind(&in_bounds); 236 __ bind(&in_bounds);
231 // Fast case: Do the load. 237 // Fast case: Do the load.
232 __ addi(scratch1, elements, 238 __ addi(scratch1, elements,
233 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 239 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
234 // The key is a smi. 240 // The key is a smi.
235 __ SmiToPtrArrayOffset(scratch2, key); 241 __ SmiToPtrArrayOffset(scratch2, key);
236 __ LoadPX(scratch2, MemOperand(scratch2, scratch1)); 242 __ LoadPX(scratch2, MemOperand(scratch2, scratch1));
237 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex); 243 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
238 // In case the loaded value is the_hole we have to check the prototype chain. 244 // In case the loaded value is the_hole we have to check the prototype chain.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 Label slow; 287 Label slow;
282 288
283 __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), 289 __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
284 JSObject::kPropertiesOffset)); 290 JSObject::kPropertiesOffset));
285 GenerateDictionaryLoad(masm, &slow, dictionary, 291 GenerateDictionaryLoad(masm, &slow, dictionary,
286 LoadDescriptor::NameRegister(), r3, r6, r7); 292 LoadDescriptor::NameRegister(), r3, r6, r7);
287 __ Ret(); 293 __ Ret();
288 294
289 // Dictionary load failed, go slow (but don't miss). 295 // Dictionary load failed, go slow (but don't miss).
290 __ bind(&slow); 296 __ bind(&slow);
291 GenerateRuntimeGetProperty(masm); 297 GenerateSlow(masm);
292 } 298 }
293 299
294 300
295 // A register that isn't one of the parameters to the load ic. 301 // A register that isn't one of the parameters to the load ic.
296 static const Register LoadIC_TempRegister() { return r6; } 302 static const Register LoadIC_TempRegister() { return r6; }
297 303
298 304
299 static void LoadIC_PushArgs(MacroAssembler* masm) { 305 static void LoadIC_PushArgs(MacroAssembler* masm) {
300 Register receiver = LoadDescriptor::ReceiverRegister(); 306 Register receiver = LoadDescriptor::ReceiverRegister();
301 Register name = LoadDescriptor::NameRegister(); 307 Register name = LoadDescriptor::NameRegister();
(...skipping 14 matching lines...) Expand all
316 322
317 LoadIC_PushArgs(masm); 323 LoadIC_PushArgs(masm);
318 324
319 // Perform tail call to the entry. 325 // Perform tail call to the entry.
320 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 326 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
321 int arg_count = 4; 327 int arg_count = 4;
322 __ TailCallExternalReference(ref, arg_count, 1); 328 __ TailCallExternalReference(ref, arg_count, 1);
323 } 329 }
324 330
325 331
326 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 332 void LoadIC::GenerateSlow(MacroAssembler* masm) {
327 // The return address is in lr. 333 // The return address is in lr.
328 334
329 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); 335 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
330 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); 336 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
331 337
332 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); 338 ExternalReference ref =
339 ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
340 int arg_count = 2;
341 __ TailCallExternalReference(ref, arg_count, 1);
333 } 342 }
334 343
335 344
336 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 345 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
337 // The return address is in lr. 346 // The return address is in lr.
338 Isolate* isolate = masm->isolate(); 347 Isolate* isolate = masm->isolate();
339 348
340 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::SlotRegister(), 349 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::SlotRegister(),
341 LoadWithVectorDescriptor::VectorRegister())); 350 LoadWithVectorDescriptor::VectorRegister()));
342 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8); 351 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8);
343 352
344 LoadIC_PushArgs(masm); 353 LoadIC_PushArgs(masm);
345 354
346 // Perform tail call to the entry. 355 // Perform tail call to the entry.
347 ExternalReference ref = 356 ExternalReference ref =
348 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 357 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
349 int arg_count = 4; 358 int arg_count = 4;
350 __ TailCallExternalReference(ref, arg_count, 1); 359 __ TailCallExternalReference(ref, arg_count, 1);
351 } 360 }
352 361
353 362
354 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 363 void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) {
355 // The return address is in lr. 364 // The return address is in lr.
356 365
357 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 366 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
358 367
359 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 368 ExternalReference ref =
369 ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
370 int arg_count = 2;
371 __ TailCallExternalReference(ref, arg_count, 1);
360 } 372 }
361 373
362 374
363 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { 375 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm,
376 LanguageMode language_mode) {
364 // The return address is in lr. 377 // The return address is in lr.
365 Label slow, check_name, index_smi, index_name, property_array_property; 378 Label slow, check_name, index_smi, index_name, property_array_property;
366 Label probe_dictionary, check_number_dictionary; 379 Label probe_dictionary, check_number_dictionary;
367 380
368 Register key = LoadDescriptor::NameRegister(); 381 Register key = LoadDescriptor::NameRegister();
369 Register receiver = LoadDescriptor::ReceiverRegister(); 382 Register receiver = LoadDescriptor::ReceiverRegister();
370 DCHECK(key.is(r5)); 383 DCHECK(key.is(r5));
371 DCHECK(receiver.is(r4)); 384 DCHECK(receiver.is(r4));
372 385
373 Isolate* isolate = masm->isolate(); 386 Isolate* isolate = masm->isolate();
374 387
375 // Check that the key is a smi. 388 // Check that the key is a smi.
376 __ JumpIfNotSmi(key, &check_name); 389 __ JumpIfNotSmi(key, &check_name);
377 __ bind(&index_smi); 390 __ bind(&index_smi);
378 // Now the key is known to be a smi. This place is also jumped to from below 391 // Now the key is known to be a smi. This place is also jumped to from below
379 // where a numeric string is converted to a smi. 392 // where a numeric string is converted to a smi.
380 393
381 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6, 394 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
382 Map::kHasIndexedInterceptor, &slow); 395 Map::kHasIndexedInterceptor, &slow);
383 396
384 // Check the receiver's map to see if it has fast elements. 397 // Check the receiver's map to see if it has fast elements.
385 __ CheckFastElements(r3, r6, &check_number_dictionary); 398 __ CheckFastElements(r3, r6, &check_number_dictionary);
386 399
387 GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow); 400 GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow,
401 language_mode);
388 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6); 402 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6);
389 __ Ret(); 403 __ Ret();
390 404
391 __ bind(&check_number_dictionary); 405 __ bind(&check_number_dictionary);
392 __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset)); 406 __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset));
393 __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset)); 407 __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset));
394 408
395 // Check whether the elements is a number dictionary. 409 // Check whether the elements is a number dictionary.
396 // r6: elements map 410 // r6: elements map
397 // r7: elements 411 // r7: elements
398 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 412 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
399 __ cmp(r6, ip); 413 __ cmp(r6, ip);
400 __ bne(&slow); 414 __ bne(&slow);
401 __ SmiUntag(r3, key); 415 __ SmiUntag(r3, key);
402 __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8); 416 __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8);
403 __ Ret(); 417 __ Ret();
404 418
405 // Slow case, key and receiver still in r3 and r4. 419 // Slow case, key and receiver still in r3 and r4.
406 __ bind(&slow); 420 __ bind(&slow);
407 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7, 421 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7,
408 r6); 422 r6);
409 GenerateRuntimeGetProperty(masm); 423 GenerateSlow(masm);
410 424
411 __ bind(&check_name); 425 __ bind(&check_name);
412 GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow); 426 GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow);
413 427
414 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6, 428 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
415 Map::kHasNamedInterceptor, &slow); 429 Map::kHasNamedInterceptor, &slow);
416 430
417 // If the receiver is a fast-case object, check the stub cache. Otherwise 431 // If the receiver is a fast-case object, check the stub cache. Otherwise
418 // probe the dictionary. 432 // probe the dictionary.
419 __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 433 __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 patcher.EmitCondition(ne); 902 patcher.EmitCondition(ne);
889 } else { 903 } else {
890 DCHECK(Assembler::GetCondition(branch_instr) == ne); 904 DCHECK(Assembler::GetCondition(branch_instr) == ne);
891 patcher.EmitCondition(eq); 905 patcher.EmitCondition(eq);
892 } 906 }
893 } 907 }
894 } // namespace internal 908 } // namespace internal
895 } // namespace v8 909 } // namespace v8
896 910
897 #endif // V8_TARGET_ARCH_PPC 911 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ic/ppc/handler-compiler-ppc.cc ('k') | src/ic/x64/handler-compiler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698